Skip to content

Commit 2d08883

Browse files
committed
WIP 2 (close)
1 parent 15814f1 commit 2d08883

File tree

4 files changed

+74
-19
lines changed

4 files changed

+74
-19
lines changed

src/image-viewer-gesture.ts

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,19 +32,30 @@ export class ImageViewerGesture extends PanGesture {
3232
this.listen();
3333
}
3434

35+
// As we handle both pinch and drag, we have to make sure we don't drag when we are trying to pinch
36+
isPinching(ev) {
37+
return ev.touches && ev.touches.length > 1;
38+
}
39+
3540
onDragStart(ev: any): boolean {
41+
if (this.isPinching(ev)) {
42+
this.abort(ev);
43+
}
44+
3645
let coord = pointerCoord(ev);
3746
this.startY = coord.y;
3847
return true;
3948
}
4049

4150
canStart(ev: any): boolean {
42-
const isPinching = ev.touches && ev.touches.length > 1;
43-
44-
return !this.component.isZoomed && !isPinching;
51+
return !this.component.isZoomed && !this.isPinching(ev);
4552
}
4653

4754
onDragMove(ev: any): boolean {
55+
if (this.isPinching(ev)) {
56+
this.abort(ev);
57+
}
58+
4859
let coord = pointerCoord(ev);
4960
this.translationY = coord.y - this.startY;
5061
this.opacity = Math.max(1 - Math.abs(this.translationY) / (10 * DRAG_THRESHOLD), .5);

src/image-viewer.component.ts

Lines changed: 55 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
Config,
1111
Platform
1212
} from 'ionic-angular';
13+
import { DIRECTION_HORIZONTAL, DIRECTION_VERTICAL } from 'ionic-angular/gestures/hammer';
1314
import { ElementRef, Renderer, Component, OnInit, OnDestroy, AfterViewInit, NgZone, ViewChild } from '@angular/core';
1415
import { DomSanitizer, SafeUrl } from '@angular/platform-browser';
1516

@@ -43,7 +44,14 @@ export class ImageViewerComponent extends Ion implements OnInit, OnDestroy, Afte
4344

4445
@ViewChild('imageContainer') imageContainer;
4546
private pinchGesture: Gesture;
47+
private adjustScale = 1;
48+
private adjustDeltaX = 0;
49+
private adjustDeltaY = 0;
50+
4651
private currentScale: number = 1;
52+
private currentDeltaX = null;
53+
private currentDeltaY = null;
54+
4755
private dblClickInAction: boolean;
4856
public isZoomed: boolean;
4957

@@ -73,9 +81,11 @@ export class ImageViewerComponent extends Ion implements OnInit, OnDestroy, Afte
7381
ngAfterViewInit() {
7482
// imageContainer is set after the view has been initialized
7583
this._zone.runOutsideAngular(() => {
76-
this.pinchGesture = new Gesture(this.imageContainer.nativeElement);
84+
this.pinchGesture = new Gesture(this.imageContainer.nativeElement, {direction: DIRECTION_HORIZONTAL | DIRECTION_VERTICAL});
7785
this.pinchGesture.listen();
7886
this.pinchGesture.on('pinch', (e) => this.onPinch(e));
87+
this.pinchGesture.on('pinchend', (e) => this.onPinchEnd(e));
88+
this.pinchGesture.on('pan', (e) => this.onPan(e));
7989
});
8090
}
8191

@@ -98,12 +108,53 @@ export class ImageViewerComponent extends Ion implements OnInit, OnDestroy, Afte
98108
this.imageContainer.nativeElement.style.transform = '';
99109

100110
this.isZoomed = !this.isZoomed;
111+
112+
if (this.isZoomed) {
113+
this.currentScale === 2;
114+
}
115+
101116
this.renderer.setElementClass(this.imageContainer.nativeElement, 'zoom', this.isZoomed);
102117
}
103118

104119
onPinch(event) {
105-
console.log(event, this.currentScale)
106-
this.currentScale = Math.max(MAX_SCALE, this.currentScale * event.scale);
107-
this.imageContainer.nativeElement.style.transform = `scale(${this.currentScale})`;
120+
this.dragGesture.abort(event);
121+
122+
this.currentScale = Math.max(1, Math.min(MAX_SCALE, this.adjustScale * event.scale));
123+
124+
if (this.currentScale === 1) {
125+
this.currentDeltaX = 0;
126+
this.currentDeltaY = 0;
127+
} else {
128+
this.currentDeltaX = this.adjustDeltaX + (event.deltaX / this.currentScale);
129+
this.currentDeltaY = this.adjustDeltaY + (event.deltaY / this.currentScale);
130+
}
131+
132+
this.setImageContainerTransform();
133+
}
134+
135+
onPan(event) {
136+
if (this.isZoomed) {
137+
this.currentDeltaX = this.adjustDeltaX + event.deltaX;
138+
this.currentDeltaY = this.adjustDeltaY + event.deltaY;
139+
140+
this.setImageContainerTransform();
141+
}
142+
}
143+
144+
onPinchEnd(event) {
145+
this.isZoomed = (this.currentScale !== 1);
146+
147+
// Saving the final transforms for adjustment next time the user interacts.
148+
this.adjustScale = this.currentScale;
149+
this.adjustDeltaX = this.currentDeltaX;
150+
this.adjustDeltaY = this.currentDeltaY;
151+
}
152+
153+
setImageContainerTransform() {
154+
const transforms = [];
155+
transforms.push(`scale(${this.currentScale})`);
156+
transforms.push(`translate(${this.currentDeltaX}px, ${this.currentDeltaY}px)`);
157+
158+
this.renderer.setElementStyle(this.imageContainer.nativeElement, 'transform', transforms.join(' '));
108159
}
109160
}

src/image-viewer.directive.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,7 @@ export class ImageViewerDirective {
1515
private _el: ElementRef
1616
) { }
1717

18-
@HostListener('click', ['$event.target'])
19-
onClick($event): void {
18+
@HostListener('click') onClick(): void {
2019
let position = this._el.nativeElement.getBoundingClientRect();
2120

2221
let imageViewer = ImageViewer.create({image: this.src || this._el.nativeElement.src, position: position});

src/image-viewer.scss

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@ image-viewer.ion-page {
4747
.image {
4848
will-change: transform;
4949
transform-origin: 0 0;
50+
51+
&.zoom {
52+
transform: scale(2);
53+
}
5054
}
5155

5256
img {
@@ -59,14 +63,4 @@ image-viewer.ion-page {
5963
transition: transform .2s ease-in-out;
6064
transform-origin: 0 0;
6165
}
62-
63-
&.zoom {
64-
.image-wrapper {
65-
overflow: auto;
66-
}
67-
68-
img {
69-
transform: scale(2);
70-
}
71-
}
7266
}

0 commit comments

Comments
 (0)