Zoom on image in Ionic?

Some solutions found? Zoom not working for me too…

Not until now sorry…

Pïnch gesture can be activated now :

You can check the code here

If anybody is interested, I made an ionic 2 module to be easily used and I made it open source (especially for this case).

Check it out here https://github.com/nikini/ionic-gallery-modal

5 Likes

Different approaches, pretty much appreciated!

1 Like

You can try photo viewer native plugin. I have used it to view my image on tap event

I have gone finally with implementing a zoom-pan directive, using hammer.js

It’s used just like this:
<img [src]="mapUri" zoom-pan>

you have to add the directive to your declarations in app.module.ts

import { Directive, ElementRef } from '@angular/core';

declare var Hammer:any;

@Directive({
    selector: '[zoom-pan]'
})
export class ZoomPanDirective {
    private element: any;

    public isZoomed: boolean;

    constructor(el: ElementRef) {
        this.element = el.nativeElement;
        this.setZoomed(false);

        this.hammerIt(this.element);

    }

    private setZoomed(zoomed:any) {
        this.isZoomed = zoomed;
        this.element.setAttribute('zoomed', this.isZoomed);
    }

    private hammerIt(elm:any) {
        let hammertime = new Hammer(elm, {});
        hammertime.get('pinch').set({
            enable: true
        });
        let posX = 0,
            posY = 0,
            scale = 1,
            last_scale = 1,
            last_posX = 0,
            last_posY = 0,
            max_pos_x = 0,
            max_pos_y = 0,
            transform = '',
            el = elm;

        hammertime.on('doubletap pan pinch panend pinchend', (ev:any) => {
            if (ev.type === 'doubletap') {
                transform =
                    'translate3d(0, 0, 0) ' +
                    'scale3d(2, 2, 1) ';
                scale = 2;
                last_scale = 2;
                try {
                    if (window.getComputedStyle(el, null).getPropertyValue('-webkit-transform').toString() !== 'matrix(1, 0, 0, 1, 0, 0)') {
                        transform =
                            'translate3d(0, 0, 0) ' +
                            'scale3d(1, 1, 1) ';
                        scale = 1;
                        last_scale = 1;
                    }
                } catch (err) { }
                el.style.webkitTransform = transform;
                transform = '';
            }

            // pan
            if (scale !== 1) {
                posX = last_posX + ev.deltaX;
                posY = last_posY + ev.deltaY;
                max_pos_x = Math.ceil((scale - 1) * el.clientWidth / 2);
                max_pos_y = Math.ceil((scale - 1) * el.clientHeight / 2);
                if (posX > max_pos_x) {
                    posX = max_pos_x;
                }
                if (posX < -max_pos_x) {
                    posX = -max_pos_x;
                }
                if (posY > max_pos_y) {
                    posY = max_pos_y;
                }
                if (posY < -max_pos_y) {
                    posY = -max_pos_y;
                }
            }

            // pinch
            if (ev.type === 'pinch') {
                scale = Math.max(.999, Math.min(last_scale * (ev.scale), 4));
            }
            if (ev.type === 'pinchend') { last_scale = scale; }

            // panend
            if (ev.type === 'panend') {
                last_posX = posX < max_pos_x ? posX : max_pos_x;
                last_posY = posY < max_pos_y ? posY : max_pos_y;
            }

            if (scale !== 1) {
                transform =
                    'translate3d(' + posX + 'px,' + posY + 'px, 0) ' +
                    'scale3d(' + scale + ', ' + scale + ', 1)';
            }

            if (transform) {
                el.style.webkitTransform = transform;
            }

            if (scale <= 1) {
                this.setZoomed(false);
            } else {
                this.setZoomed(true);
            }
        });
    }
}
3 Likes

artaud, good day ! I am trying to use your zoom-pan directive … it working perfectly. But above the image I drawing html span with special coordinates … something like hot spots … when I am trying zoom image … hot spots disappear … Could your suggest please how to implement zoom image with hot spots ?

artaud, works like a charm. I transformed it into a component. Thanx for your work!

@chrisweber @artaud @anton_klochko For me it works really good on iOS but on Android is really slow on zooming and movement by dragging is bugged. Any fix? Thanks in advance :smiley:

I also stumbled over this problem in ionic but I found a really good zoom component that had no performance problems on android.

Only problem at the moment, it is not AOT ready it seems, but as a workaround you can just copy the component in your own project.

What a hero! :sunglasses: