1. #1
    Sencha - Training Team mrsunshine's Avatar
    Join Date
    Sep 2008
    Location
    Germany - Darmstadt
    Posts
    691
    Vote Rating
    12
    mrsunshine will become famous soon enough

      3  

    Default Pinch Zoom Scrollable Image

    Pinch Zoom Scrollable Image


    Update: i removed the first example and replaced it by a class which solves the problem

    Pinch Zoom Image, creates a pinch zoom able image in a scrollable container
    Can be uses with dynamic size from the height width of the container.

    Features:
    • pinch zoom to scale the image
    • with scrollbars if image size need this
    • center scrollers while zooming (has to be improved)
    Example 1:
    PHP Code:
     {
     
    flex1,
     
    xtype'pinchzoomimage',
     
    src'/resources/images/casinomenu.jpg'
     

    Example 2
    PHP Code:
     {
     
    xtype'pinchzoomimage',
     
    src'/resources/images/casinomenu.jpg',
     
    width320,
     
    height440
     

    The class
    PHP Code:
    /**
     * Pinch Zoom Image
     * creates a pinch zoom able image in a scrollable container
     *
     * Can be uses with dynamic size from the height width of the container
     *
     * @example
     *     {
     *         flex: 1,
     *         xtype: 'pinchzoomimage',
     *         src: '/resources/images/casinomenu.jpg'
     *     }
     *
     * or with fixed sizes
     *
     * {
     *         xtype: 'pinchzoomimage',
     *         src: '/resources/images/casinomenu.jpg',
     *         width: 320,
     *         height: 440
     *     }
     *
     *
     * @author     Nils Dehl <mail@nils-dehl.de>
     * @www     http://www.nils-dehl.de
     *
     * @version: 1.0.0
     */
    Ext.define('Ux.PinchZoomImage', {
        
    extend'Ext.Container',
        
    xtype'pinchzoomimage',
        
    alias'widget.pinchzoomimage',


        
    config: {
            
    /**
             * Image src url
             *
             * @type String
             */
            
    src'',


            
    /**
             * height of the pinchzoom image
             *
             * @type int
             */
            
    heightnull,


            
    /**
             * width of the pinchzoom image
             *
             * @type int
             */
            
    widthnull,


            
    scrollabletrue,
            
    listeners: {
                
    painted'initImage'
            
    }
        },


        
    /**
         * init the image in the scrollable container
         *
         * @param {} newImageSrc
         */
        
    initImage: function(newImageSrc) {
            var 
    height this.getHeight() || this.element.getHeight(),
                
    width this.getWidth() || this.element.getWidth(),
                
    src this.getSrc() || newImageSrc,
                
    image null;


                if (
    Ext.isString(src) && src !== '') {
                
    image Ext.create('Ext.Img', {
                    
    // set mode auf empty to create a real image tag
                    
    mode'',
                    
    heightheight,
                    
    widthwidth,
                    
    srcsrc,
                    
    listeners: {
                        
    pinch: {
                            
    element'element',
                            
    fnthis.onImagePinch


                        
    },
                        
    doubletap: {
                            
    element'element',
                            
    fnthis.onImageDoubletap
                        
    }
                    }
                });


                
    this.add(image);
            }
        },


        
    /**
         * reset the image to initial size
         *
         * @param {} e
         */
        
    onImageDoubletap: function(e) {
            var 
    initialWidth  this.getInitialConfig('width'),
                
    initialHeight this.getInitialConfig('height'),
                
    container     this,
                
    image         this.element;




            
    container.setWidth(initialWidth);
            
    container.setHeight(initialHeight);
            
    image.setWidth(initialWidth);
            
    image.setHeight(initialHeight);
        },


        
    /**
         * on image pinch scale the image size
         * and set the scroller to a new position
         *
         * @param {} e eventobject
         */
        
    onImagePinch: function(e) {
            var 
    initialWidth  this.getInitialConfig('width'),
                
    initialHeight this.getInitialConfig('height'),
                
    newWidth      initialWidth e.scale,
                
    newHeight     initialHeight e.scale,
                
    container     this,
                
    image         this.element,
                
    scroller this.up('container').getScrollable().getScroller(),
                
    pos scroller.getMaxPosition();




            
    container.setWidth(newWidth);
            
    container.setHeight(newHeight);
            
    image.setWidth(newWidth);
            
    image.setHeight(newHeight);
            
    scroller.scrollTo(pos.x/2pos.y/2);
        },


        
    /**
         * if set Src is called and an
         * old image exist destroy the old
         * one and add the new one
         *
         * @param {} newImageSrc
         * @param {} oldImageSrc
         */
        
    applySrc: function(newImageSrc) {
            var 
    oldImage this.down('img');


            if (
    Ext.isObject(oldImage)) {
                
    oldImage.destroy();
            }


            
    this.initImage(newImageSrc);
        }


    }); 

  2. #2
    Touch Premium Member hotdp's Avatar
    Join Date
    Nov 2010
    Location
    Denmark
    Posts
    603
    Vote Rating
    14
    hotdp will become famous soon enough

      0  

    Default


    Great job!
    I have some features that would be awesome to have:
    • It always scale from upper left corner. Its not very user friendly, is it possible to zoom from the center of the pitch location?
    • It behaves strange when you first zoom in, take a break and zoom some more. Looks like it starts to scale from 1 instead of the pinchend scale size. But I might be wrong here?

  3. #3
    Sencha User
    Join Date
    Nov 2010
    Posts
    390
    Vote Rating
    6
    gkatz is on a distinguished road

      0  

    Default


    Nice...
    any chance of transforming this into component structure?

  4. #4
    Sencha - Training Team mrsunshine's Avatar
    Join Date
    Sep 2008
    Location
    Germany - Darmstadt
    Posts
    691
    Vote Rating
    12
    mrsunshine will become famous soon enough

      0  

    Default


    Quote Originally Posted by hotdp View Post
    • It always scale from upper left corner. Its not very user friendly, is it possible to zoom from the center of the pitch location?
    yeah, an idea could be to correct the scroll position while pinch i will look into this

    Quote Originally Posted by hotdp View Post
    • It behaves strange when you first zoom in, take a break and zoom some more. Looks like it starts to scale from 1 instead of the pinchend scale size. But I might be wrong here?
    thats at the moment cause i start with the initial with and hight it could be changed to the current width and height

  5. #5
    Sencha - Training Team mrsunshine's Avatar
    Join Date
    Sep 2008
    Location
    Germany - Darmstadt
    Posts
    691
    Vote Rating
    12
    mrsunshine will become famous soon enough

      0  

    Default


    Quote Originally Posted by gkatz View Post
    Nice...
    any chance of transforming this into component structure?
    this will be the next step

  6. #6
    Touch Premium Member hotdp's Avatar
    Join Date
    Nov 2010
    Location
    Denmark
    Posts
    603
    Vote Rating
    14
    hotdp will become famous soon enough

      0  

    Default


    Quote Originally Posted by mrsunshine View Post
    yeah, an idea could be to correct the scroll position while pinch i will look into this
    This is the biggest problem. I have tried some things myself but run into placements problems. If I scale from center the image container will not place the image correct. (can't scroll to the left/left-upper-corner). But I will keep hitting F5 on this thread and hope you will come up with something.

    Ps. When this component is working perfectly I will try to combine it with the Carousel.

  7. #7
    Sencha User
    Join Date
    Jan 2012
    Location
    New York, NY
    Posts
    5
    Vote Rating
    0
    dphunkt is on a distinguished road

      0  

    Default


    I've had some success adding something similar to a carousel. I hooked in to the onItemAdd function and set up my pinch listeners there. Also, I was able to override the onDragStart function and prevent the flick to the prev/next carousel item if the image isn't scrolled all the way to the edge of its scrollable container. Still working on the resize centering issue. Resetting the scroll position keeps it centered but it's jumpy.

    Code:
    Ext.define('PinchCarousel', {
        extend: 'Ext.Carousel',
        xtype: 'slideshow',
        requires: [
             //'Ext.Img'
        ],
        config: {
            id: 'slideShow'
        },
    /*
        beforeInitialize: function() {
            
        },
    */
        onItemAdd: function(item, index){
            var scale, perc, size,
                el = item.element;
    
            el.on({
    /*
                doubletap: function(e, node, options, eOpts) {
                    console.log(item);
                },
    */
                pinchstart: function(e, node, options, eOpts) {
                    size = el.down('.carousel-item-img').getSize();
                },
                pinch: function(e, node, options, eOpts) {                
                    var newScale = e.scale,
                        scroller = item.getScrollable().getScroller(),
                        width = size.width*newScale, 
                        height = size.height*newScale,
                        pos = scroller.getMaxPosition();
                    
    
    
                    if (height > 1024 || width > 1024 || height < 160 || width < 160) return;
                    
                    el.down('.carousel-item-img').setSize(width, height);
    
    
                    //keeps it centered but jumpy
                    scroller.scrollTo(pos.x/2, pos.y/2);
                },
                pinchend: function() {
                    //item.getScrollable().getScroller().refresh();
                }
            });
            
            this.callParent(arguments);
        },
        onDragStart: function(e) {
            var scroller = this.getActiveItem().getScrollable().getScroller();
            //ensure the image component is scrolled all the way to the edge of its scrollable container
            if(e.targetTouches.length == 1 && (e.deltaX < 0 && scroller.getMaxPosition().x === scroller.position.x) || (e.deltaX > 0 && scroller.position.x == 0)) {
                this.callParent(arguments);
            }
        },
        onDrag: function(e) {
            //console.log(this.getActiveItem().getScrollable().getScroller().position.x);
            if(e.targetTouches.length == 1)
                this.callParent(arguments);
        },
        onDragEnd: function(e) {
            if(e.targetTouches.length < 2)
                this.callParent(arguments);
        }
    });

  8. #8
    Sencha - Training Team mrsunshine's Avatar
    Join Date
    Sep 2008
    Location
    Germany - Darmstadt
    Posts
    691
    Vote Rating
    12
    mrsunshine will become famous soon enough

      0  

    Default


    thanks for the tip with the scrollbar handling,
    i added it to my code, like you said it if only to smoothed

  9. #9
    Touch Premium Member hotdp's Avatar
    Join Date
    Nov 2010
    Location
    Denmark
    Posts
    603
    Vote Rating
    14
    hotdp will become famous soon enough

      0  

    Default


    Hi,
    Have you guys had luck solving the center zoom issue?

  10. #10
    Sencha - Training Team mrsunshine's Avatar
    Join Date
    Sep 2008
    Location
    Germany - Darmstadt
    Posts
    691
    Vote Rating
    12
    mrsunshine will become famous soon enough

      0  

    Default


    i updatet the example respectively replaced it by my own class.
    i added the scoller center solution from dphunkt

    you can find the solution in post #1