In the demo (https://pdfviewer.net/simple) I could pinch to zoom the PDF with the macbook trackpad, but on mobile (using Firefox mobile on Android) I zoom the whole page, not just the embedded PDF.
Is doing so a new feature, or is this possible already, provided the right integration?
If it is a feature, how hard would it be to integrate using hammerjs? Currently, I am looking into different PDF plugins (along with ng2-pdf-viewer and ng2-pdfjs-viewer) and wondering, if I had to integrate it myself, a fork of which would be the easiest.
@codehippie1 @VadimDez I'm adding you to the loop. I suppose you've either already solved the problem, or you're interested in solving the problem. Let's do it with joint forces!
@philly-vanilly The PDF viewer behaves the same on my iPad. That's a bit surprising. It might be a feature on a small cell-phone, but I didn't expect that on a much larger iPad.
I've found it. OSX maps the pinch gesture to mouse-wheel events.
In order to implement zoom and pinch yourself using Hammer.js, all you have to do it to call this methods when you catch a zoom / pinch event:
PDFViewerApplication.zoomOut(1);
PDFViewerApplication.zoomIn(1);
Here's the original implementation: https://github.com/mozilla/pdf.js/blob/50bc4a18e8c564753365d927d5ec6a6d2cce3072/web/app.js#L2446
Maybe you also need to add this line:
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
You may also want to look at https://gist.github.com/jsprpalm/12217feab2f1acc14bd8e8508291619e and - probably even better - at https://gist.github.com/larsneo/bb75616e9426ae589f50e8c8411020f6.
@philly-vanilly If you try one of these gists, can you tell me if it works? This looks like a nice feature for ngx-extended-pdf-viewer. However, I wonder which side-effects the feature has.
Did anyone try already the above mentioned gists or any other solutions? It would be nice to have them incorporated into the library. It's a very useful and sometimes critical feature to have.
I placed this code in the component-wrapper and it works quite well. let me know if anyone finds a way to optimize it.
export class MyPdfViewer {
private enablePinchZoom: boolean = false;
private viewer: any;
private container: any;
private startX: number = 0;
private startY: number = 0;
private initialPinchDistance: number = 0;
private pinchScale: number = 1;
constructor(private _zone: NgZone) {}
private onViewerTouchStart(event: TouchEvent): EventListener {
if (!this.enablePinchZoom) {
return;
}
if (event.touches.length > 1) {
this.startX = (event.touches[0].pageX + event.touches[1].pageX) / 2;
this.startY = (event.touches[0].pageY + event.touches[1].pageY) / 2;
this.initialPinchDistance = Math.hypot((event.touches[1].pageX - event.touches[0].pageX), (event.touches[1].pageY - event.touches[0].pageY));
} else {
this.initialPinchDistance = 0;
}
}
private onViewerTouchMove(event: TouchEvent): EventListener {
if (!this.enablePinchZoom) {
return;
}
if (this.initialPinchDistance <= 0 || event.touches.length < 2) { return; }
if (this.pinchScale !== 1) { event.preventDefault(); }
const pinchDistance = Math.hypot((event.touches[1].pageX - event.touches[0].pageX), (event.touches[1].pageY - event.touches[0].pageY));
const originX = this.startX + this.container.scrollLeft;
const originY = this.startY + this.container.scrollTop;
this.pinchScale = pinchDistance / this.initialPinchDistance;
this.viewer.style.transform = `scale(${this.pinchScale})`;
this.viewer.style.transformOrigin = `${originX}px ${originY}px`;
}
private onViewerTouchEnd(): EventListener {
if (!this.enablePinchZoom) {
return;
}
const PDFViewerApplication: any = (window as any).PDFViewerApplication;
if (this.initialPinchDistance <= 0) { return; }
this.viewer.style.transform = `none`;
this.viewer.style.transformOrigin = `unset`;
PDFViewerApplication.pdfViewer.currentScale *= this.pinchScale;
const rect = this.container.getBoundingClientRect();
const dx = this.startX - rect.left;
const dy = this.startY - rect.top;
this.container.scrollLeft += dx * (this.pinchScale - 1);
this.container.scrollTop += dy * (this.pinchScale - 1);
this.resetPinchZoomParams();
}
@HostListener('document:webviewerloaded')
onWebViewerLoaded(): void {
this.enablePinchZoom = true;
this.initializePinchZoom();
}
private resetPinchZoomParams(): void {
this.startX = this.startY = this.initialPinchDistance = 0;
this.pinchScale = 1;
}
private initializePinchZoom(): void {
this.viewer = document.getElementById('viewer');
this.container = document.getElementById('viewerContainer');
this._zone.runOutsideAngular(() => {
document.addEventListener('touchstart', this.onViewerTouchStart.bind(this));
document.addEventListener('touchmove', this.onViewerTouchMove.bind(this), { passive: false });
document.addEventListener('touchend', this.onViewerTouchEnd.bind(this));
});
}
}
I've started to add your class to ngx-extended-pdf-viewer, but it doesn't seem to work yet. Maybe I've got more luck tomorrow!
It's working for me (tested in 3.7.2 version, bot hAndroid and iOS). The only thing missing (in my opinion) is the ability to set scale limits for zoom in/out. You can currently pinch-zoom out until the doc completely desappears. Would be nice to be able to set it with options or at least to have some default min/max scale preset (like in the desktop mode).
Good idea. Thanks!
BTW: the only reason why this ticket is still open is I don't check the finger position yet:
Most helpful comment
I've started to add your class to
ngx-extended-pdf-viewer, but it doesn't seem to work yet. Maybe I've got more luck tomorrow!https://pdfviewer.net/touch-gestures