1. #1
    Sencha User
    Join Date
    Apr 2012
    Location
    Toronto, Canada
    Posts
    92
    Vote Rating
    12
    iSmartDevice is on a distinguished road

      0  

    Default Image gallery component with Ext.List

    Image gallery component with Ext.List


    Hi,
    I just wanted to share the image gallery component with you. It might be useful for those who need.

    http://www.appshowcase.net/apps/gallery/

    Screen Shot 2012-05-22 at 4.20.37 PM.jpg
    It is based on the image gallery in "airbnb.com" and still needs to be upgraded. If you have a better idea to implement the image gallery, do not hesitate to update it.

    Code:
    Ext.define("Gallery.view.Main", {    extend: 'Ext.tab.Panel',
        requires: [
            'Ext.TitleBar',
            'Gallery.view.ImageGallery'
        ],
        config: {
            tabBarPosition: 'bottom',
    
    
            items: [
                {
                    title: 'Gallery',
                    iconCls: 'action',
    
    
                    items: [
                        {
                            docked: 'top',
                            xtype: 'titlebar',
                            title: 'Gallery',
                            style: 'margin-bottom:10px',
                        },
                        {
                            xtype: 'imageGallery',
                            style: 'margin:10px',
                            scrollable: false,
                            store: {
                                data:[
                                    {photo: 'http://2.bp.blogspot.com/-SwRvvHer_wQ/T6GhgnQoS0I/AAAAAAAHhkY/iyxaoyoC-2g/s800/Kia-K9-01.jpg'},
                                    {photo: 'http://4.bp.blogspot.com/-8iGyCfFuLuU/T5QA-1t4QTI/AAAAAAAAAXg/izbeFI2PvC0/s1600/korea.jpg'},
                                    {photo: 'http://www.dynamicdrive.com/cssexamples/media/ocean.jpg'},
                                    {photo: 'http://media.lonelyplanet.com/lpi/24744/24744-14/469x264.jpg'},
                                    {photo: 'http://3.bp.blogspot.com/-kyrXb2orUgA/Te9KO0AxR5I/AAAAAAAAErY/X_XkbgU107Q/s1600/Blue_Ocean_17723522_std.jpg'},
                                    {photo: 'http://1.bp.blogspot.com/-iOPb28o8svc/TpvN-dWORKI/AAAAAAAAAuw/8pPLujrCSQ0/s1600/toronto.jpg'},
                                    {photo: 'http://www.nyspsych.org/SiteCollectionImages/NYCSkylinelandingpage.jpg'},
                                    {photo: 'http://www.ebaytemplate.info/wp-content/gallery/germany/elbe-river-dresden-germany.jpg'},
                                    {photo: 'http://www.feratel.com/uploads/pics/Italien_1_01.jpg'},
                                    {photo: 'http://blog.educationusa.or.kr/wp-content/uploads/2008/07/dokdo-islets.jpg'},
                                    {photo: 'http://www.yarbridgeinn.co.uk/user/sites/yarbridgeinn.co.uk/files/UK%20Travel%20on%20a%20Shoestring%20Budget.jpg'},
                                    {photo: 'http://villaluxe.com/wp-content/gallery/pamillaretreat/maxico-palmilla-04.jpg'},
                                    {photo: 'http://www.cbrconnection.com/agent_files/Hawaii%20web9.jpg'},
                                ],
                            },
                        },
                    ]
                }
            ]
        }
    });
    Code:
    .galleria-image-nav-right:hover, .galleria-image-nav-left:hover {
        opacity: .8;
        -ms-filter: "alpha(opacity=80)";
        filter: alpha(opacity=80);
    }
    
    
    .galleria-image-nav-left, .galleria-image-nav-right {
        cursor: pointer;
        width: 23px;
        height: 56px;
        /*position: absolute;
        z-index: 2;*/
        background-position: 0 0;
        background-image: url(../images/slideshow-arrows.png);
        background-repeat: no-repeat;
    }
    
    
    .galleria-image-nav-left {
        -moz-border-radius-topleft: 3px;
        -moz-border-radius-bottomleft: 3px;
        -webkit-border-radius: 3px 0 0 3px;
        border-radius: 3px 0 0 3px;
    }
    
    
    .galleria-image-nav-right {
        /*position: absolute;*/
        -moz-border-radius-topright: 3px;
        -moz-border-radius-bottomright: 3px;
        -webkit-border-radius: 0 3px 3px 0;
        border-radius: 0 3px 3px 0;
        left: auto;
        right: 0;
        background-position: -23px 0;
        z-index: 2;
    }
    
    
    .galleria-image-nav-left:active
    {
        background-position:-46px top;
    }
    
    
    .galleria-image-nav-right:active
    {
        background-position:-69px top;
    }
    
    
    .galleria .x-list-normal .x-list-item:first-child .x-list-item-label {
        border-top: 0;
    }
    
    
    .galleria .x-list-normal .x-list-item .x-list-item-label {
        border-top: 0;
    }
    
    
    .galleria .x-list-normal .x-list-item:last-child .x-list-item-label {
        border-bottom: 0;
    }
    
    
    .galleria .x-list-item
    {
        background: white;
        padding: 2px;
        border: 1px solid #BABABA;
        height: 46px;
        width: 46px;
        margin: 5px 0 5px 5px;
        float: left;
        cursor: pointer;
        /*z-index: 2;*/
    }
    
    
    .galleria .x-list-item img
    {
        display: block; 
        width: 40px; 
        height: 40px; 
        top: 0px; 
        left: 0px;
        position:absolute;
        top: 2px!important;
        left: 2px!important;
    }
    
    
    .galleria .gallery-image-selected {
        background: #EE2A96;
        border-color: #AE0061;
        -moz-box-shadow: 0 0 4px 3px rgba(255,94,188,0.6);
        -webkit-box-shadow: 0 0 4px 3px rgba(255,94,188,0.6);
        box-shadow: 0 0 4px 3px rgba(255,94,188,0.6);
    }
    
    
    .galleria .x-img {
        background-repeat: no-repeat;
        background-size: auto 100%;
        background-position: center;
        border:solid 1px #d0d0d0;
    }
    Code:
    Ext.define('Gallery.view.ImageGallery', {        extend: 'Ext.Container',
        xtype: 'imageGallery',
        requires: [
            'Ext.Img',
        ],
        
        config:{
            cls: 'galleria',
            listeners:{
                painted: 'onPainted',
            },
            
            items:[
                {
                    xtype: 'image',
                    which: 'galleria_image',
            height: Ext.os.is.Phone ? '10em' : '20em',
                },
                {
                    xtype:'panel',
                    layout: 'hbox',
                    style: 'border: 1px solid #D0D0D0;margin-top:5px',
                    
                    items: [
                        {
                            xtype:'button',
                            which: 'nav_left',
                            nav_direction: 1,
                            cls: 'galleria-image-nav-left',
                            style: 'border:0',
                            pressedCls: '',
                        },
                        {
                            //give it an xtype of list for the list component
                            xtype: 'list',
                            which: 'thumnail_list',
                            flex: 1,
                            padding: '0 0 0 0',
                            scrollable: {
                                direction: 'horizontal',
                                directionLock: true
                            },
                            selectedCls : 'gallery-image-selected',
                            pressedCls: '',
                            inline: {
                                wrap: false
                            },
                            //set the itemtpl to show the fields for the store
                            /*itemTpl: '<img src="{photo}" style="display: block; width: 40px; height: 40px; top: 0px; left: 0px; opacity: 0.6;">',*/
                            itemTpl: '<img src="{photo}">',
                        },
                        {
                            xtype:'button',
                            which: 'nav_right',
                            nav_direction: 2,
                            cls: 'galleria-image-nav-right',
                            pressedCls: '',
                            style: 'border:0',
                        }
                    ]
                }
            ],
            
            store: null
        },
        
        galleria_image: null,
        thumnail_list: null,
        nav_left: null,
        nav_right: null,
        current_image_index: 0,
        
        initialize: function () {
            // Initialize parent.
            this.callParent(arguments);
            
            this.galleria_image = this.down('image[which=galleria_image]');
            this.thumnail_list = this.down('list[which=thumnail_list]');
            
            this.nav_left = this.down('button[which=nav_left]');
            this.nav_right = this.down('button[which=nav_right]');
            
            this.thumnail_list.on('itemtap', this.onChangeImage, this);
            this.nav_left.on('tap', this.onNavLeft, this);
            this.nav_right.on('tap', this.onNavRight, this);
        },
        
        onNavLeft: function(btn, e, eOpts){
            this.current_image_index--;
            if(this.current_image_index < 0)
                this.current_image_index = this.getStore().data.length-1;
                
            this.moveSelection(btn,e,eOpts);
        },
        
        onNavRight: function(btn, e, eOpts){
            this.current_image_index++;
            if(this.current_image_index > this.getStore().data.length-1)
                this.current_image_index = 0;
                
            this.moveSelection(btn,e,eOpts);
        },
        
        moveSelection: function(btn, e, eOpts) {
            var buttonRight = this.nav_right.element;
            var buttonLeft = this.nav_left.element;
            
            var currentImageItem = this.thumnail_list.getInnerItems()[0].element.dom.childNodes[this.current_image_index];
            var scrollPosition = this.thumnail_list.getScrollable().getScroller().position;
            var currentImageItemStartX = currentImageItem.offsetLeft-currentImageItem.offsetTop;
            var currentImageItemEndX = currentImageItemStartX+currentImageItem.offsetTop+currentImageItem.offsetWidth;
            
            var offsetLeftX_Left = buttonLeft.dom.offsetLeft+buttonLeft.dom.offsetWidth;
            var offsetLeftX_Right = buttonRight.dom.offsetLeft-buttonRight.dom.offsetWidth;
                
            if( currentImageItemEndX-scrollPosition.x > offsetLeftX_Right ){
                this.thumnail_list.getScrollable().getScroller().scrollTo((currentImageItemEndX-offsetLeftX_Right), scrollPosition.y, true);
            }
            else if(scrollPosition.x > currentImageItemStartX){
                this.thumnail_list.getScrollable().getScroller().scrollTo(scrollPosition.x-(scrollPosition.x - currentImageItemStartX),scrollPosition.y,true);
            }
            else if(scrollPosition.x > currentImageItemStartX){
                this.thumnail_list.getScrollable().getScroller().scrollTo(0,scrollPosition.y,true);
            }
            
            
            this.thumnail_list.select(this.current_image_index);
            this.galleria_image.setSrc(this.getStore().data[this.current_image_index].photo);
        },
        
        onChangeImage: function( view, index, target, record, e, eOpts ) {
            this.current_image_index = index;
            this.galleria_image.setSrc(record.data.photo);
        },
        
        onPainted: function( cmp, eOpts ){
            if(this.getStore() && this.thumnail_list && this.galleria_image){
                this.thumnail_list.setStore(this.getStore());
                
                if(this.getStore().data.length > 0){
                    this.thumnail_list.select(0);
                    this.galleria_image.setSrc(this.getStore().data[0].photo);
                }
            }
        }
    });
    Attached Images

  2. #2
    Sencha User
    Join Date
    Aug 2011
    Location
    London
    Posts
    407
    Vote Rating
    18
    digeridoopoo will become famous soon enough

      0  

    Default Thanks :-)

    Thanks :-)


    Great work, thanks for sharing. It looks nice, is there a live example?

    :-)

  3. #3
    Sencha User
    Join Date
    Apr 2012
    Location
    Toronto, Canada
    Posts
    92
    Vote Rating
    12
    iSmartDevice is on a distinguished road

      0  

  4. #4
    Sencha User armode's Avatar
    Join Date
    Nov 2011
    Location
    Germany / Darmstadt
    Posts
    64
    Vote Rating
    4
    armode is on a distinguished road

      0  

    Default


    Nice work!
    Do you know, that it doesn't render right on a smartphone (iPhone 4), because there is not enough space for the panel and the bottom navigation bar?
    Maybe you could use a carousel, instead of the panel to display the photos. On a small device you could hide the bottom navigation bar and navigate via swiping.
    Maybe you can use the ImageViewer component from Chris, that allows pinching and viewing more then one photo in a carousel!
    Hope this helps ;-)

  5. #5
    Sencha User
    Join Date
    Apr 2012
    Location
    Toronto, Canada
    Posts
    92
    Vote Rating
    12
    iSmartDevice is on a distinguished road

      0  

    Default


    I fixed the size issue in the component by adding "height: Ext.os.is.Phone ? '10em' : '20em'".

    I like your idea. Thanks for letting me know!!

  6. #6
    Sencha - Senior Forum Manager mitchellsimoens's Avatar
    Join Date
    Mar 2007
    Location
    Gainesville, FL
    Posts
    37,330
    Vote Rating
    847
    mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute

      0  

    Default


    Nice little app!
    Mitchell Simoens @SenchaMitch
    Sencha Inc, Senior Forum Manager
    ________________
    Check out my GitHub, lots of nice things for Ext JS 4 and Sencha Touch 2
    https://github.com/mitchellsimoens

    Think my support is good? Get more personalized support via a support subscription. https://www.sencha.com/store/

    Need more help with your app? Hire Sencha Services services@sencha.com

    Want to learn Sencha Touch 2? Check out Sencha Touch in Action that is in print!

    When posting code, please use BBCode's CODE tags.

  7. #7
    Sencha User
    Join Date
    Aug 2010
    Posts
    10
    Vote Rating
    0
    abdullah.hafidh is on a distinguished road

      0  

    Default


    It's actually really nice, but there are few bugs when I tried on Chrome browser, here is the screen shot

    Untitled.jpg

  8. #8
    Sencha User
    Join Date
    Apr 2012
    Location
    Toronto, Canada
    Posts
    92
    Vote Rating
    12
    iSmartDevice is on a distinguished road

      0  

    Default


    It might seem CSS is not applied to the web page. Could you please tell me which version of Chrome you use? My browser is 19.0.1084.53.

    Thanks!

  9. #9
    Sencha User
    Join Date
    Aug 2010
    Posts
    10
    Vote Rating
    0
    abdullah.hafidh is on a distinguished road

      0  

    Default


    Quote Originally Posted by iSmartDevice View Post
    It might seem CSS is not applied to the web page. Could you please tell me which version of Chrome you use? My browser is 19.0.1084.53.

    Thanks!
    I'm using Chrome version 19.0.1084.52 m

    Thanks

  10. #10
    Sencha User
    Join Date
    May 2013
    Posts
    1
    Vote Rating
    0
    Salomonsan is on a distinguished road

      0  

    Default


    Hey everyone,

    i try to start the Gallery by tab a button, but it don work (show screenshot)
    can anyone help me please ?

    thx an greats
    Attached Images