EmilioSG
EmilioSG

Reputation: 380

Ionic 3 image pinch and double tap zoom

I want to show a zoomable SVG image inside an ion-tab on an Ionic 3 project. The effect I am looking for is just a regular pinch and double tap zoom, nothing special.

I've tried different combinations, but I can't make it work. This is what I have right now:

HTML:

<ion-content>
  <ion-scroll scrollX="true" scrollY="true" zoom="true" overflow-scroll="false" class="scroll-view" min-zoom="1" maxZoom="10">
    <img src="assets/img/image.svg">
  </ion-scroll>
</ion-content>

CSS:

.scroll-view{
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
}

Any ideas? Thanks!

Upvotes: 4

Views: 18507

Answers (4)

Amit Pandey
Amit Pandey

Reputation: 307

Zoom, pinch, double tap zoom of Image (tested in Ionic 4).

Use Photo Viewer.

Works with live URL only.

In app.module.ts

import { PhotoViewer } from '@ionic-native/photo-viewer/ngx';

...

providers: [
    PhotoViewer, ...
],

In custom.ts

import { PhotoViewer } from
'@ionic-native/photo-viewer/ngx';

...

constructor(private photoViewer: PhotoViewer) { }

...

showPhoto()
{
    console.log("showPhoto");
   this.photoViewer.show('https://dummyimage.com/600x400/000/fff');
}

In custom.html

<img (click)="showPhoto()" />

Upvotes: 1

Avatarantella
Avatarantella

Reputation: 99

I've only tried this with an inline SVG image, but I used the svg-pan-zoom library (https://www.npmjs.com/package/svg-pan-zoom) along with hammerjs (https://www.npmjs.com/package/hammerjs). The svg-pan-zoom library says it works with SVGs in HTML object and embed elements as well.

Install them into your project with npm, import them into your component, them implement them according the instructions for the svg-pan-zoom library.

HTML:

<ion-content>
    <div class="zoom">
        <svg id="svg" class="svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="width:100%;height:100%;">...</svg>
    </div>
</ion-content>

CSS:

.zoom {
    position: fixed;
    width: 100%;
    height: 100%;
}

Component:

import { Component } from '@angular/core';
import svgPanZoom from 'svg-pan-zoom';
import Hammer from 'hammerjs';

@Component({
    selector: 'page-map',
    templateUrl: 'map.html'
})
export class MapPage {
    panZoom:any;

    constructor(){ }

    ngOnInit(){
        let eventsHandler;
        eventsHandler = {
            haltEventListeners: ['touchstart', 'touchend', 'touchmove', 'touchleave', 'touchcancel'], 
            init: function(options) {
                var instance = options.instance, initialScale = 1, pannedX = 0, pannedY = 0

               // Init Hammer
               // Listen only for pointer and touch events
               this.hammer = Hammer(options.svgElement, {
                   inputClass: Hammer.SUPPORT_POINTER_EVENTS ? Hammer.PointerEventInput : Hammer.TouchInput
               })

               // Enable pinch
               this.hammer.get('pinch').set({enable: true})

               // Handle double tap
               this.hammer.on('doubletap', function(ev){
                   instance.zoomIn()
               })

               // Handle pan
               this.hammer.on('panstart panmove', function(ev){
                   // On pan start reset panned variables
                   if (ev.type === 'panstart') {
                       pannedX = 0
                       pannedY = 0
                   }

                   // Pan only the difference
                   instance.panBy({x: ev.deltaX - pannedX, y: ev.deltaY - pannedY})
                   pannedX = ev.deltaX
                   pannedY = ev.deltaY
               })

               // Handle pinch
               this.hammer.on('pinchstart pinchmove', function(ev){
                   // On pinch start remember initial zoom
                   if (ev.type === 'pinchstart') {
                       initialScale = instance.getZoom()
                       instance.zoom(initialScale * ev.scale)
                   }

                   instance.zoom(initialScale * ev.scale)

               })

               // Prevent moving the page on some devices when panning over SVG
               options.svgElement.addEventListener('touchmove', (e) => { e.preventDefault(); });
               }, 
               destroy: function(){
                   this.hammer.destroy()
               }
           }

           let options = {
               controlIconsEnabled: false,
               customEventsHandler: eventsHandler
           };

           this.panZoom = svgPanZoom('#svg', options);
    }

Upvotes: 1

user4564782
user4564782

Reputation:

It seems that Ionic Scroll is facing some issues and a issue still open in Ionic Github, so I developed a component that uses Gesture to pinch and pan. This will allow you to zoom any element in the screen, images, div's and etc...

you can use the component by simple including it in your app.

Import ZoomAreaModule.forRoot() in your app's main module

import { ZoomAreaModule } from 'ionic2-zoom-area';

@NgModule({
    ...
    imports: [
      ...
      ZoomAreaModule.forRoot()
    ],
    ...
})
export class AppModule {}

and then you can use zoom-area component in your HTML file

<zoom-area> <img src="image-to-zoom.jpg" alt="zoom it" /> </zoom-area>

for more documentation and explanation you can check the Github page of zoom-area component.

https://github.com/leonardosalles/ionic2-zoom-area

Upvotes: 6

SMAGreg
SMAGreg

Reputation: 48

I've got the same trouble since a while. Today, this issue not yet solved (https://github.com/driftyco/ionic/issues/6482). I turned around this by using a non ionic2 team component (kind of image viewer randomly found on github). But i don't feel satisfied of this solution...

You can also try to follow this : https://forum.ionicframework.com/t/image-pinch-and-zoom-in-ionic-working-code/72850?source_topic_id=45910 seems like some people figured out how to make it work there

Upvotes: 1

Related Questions