-
14 Mar 2012 4:11 PM #1
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 2PHP Code:{
flex: 1,
xtype: 'pinchzoomimage',
src: '/resources/images/casinomenu.jpg'
}
The classPHP Code:{
xtype: 'pinchzoomimage',
src: '/resources/images/casinomenu.jpg',
width: 320,
height: 440
}
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
*/
height: null,
/**
* width of the pinchzoom image
*
* @type int
*/
width: null,
scrollable: true,
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: '',
height: height,
width: width,
src: src,
listeners: {
pinch: {
element: 'element',
fn: this.onImagePinch
},
doubletap: {
element: 'element',
fn: this.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/2, pos.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);
}
});
trainings / workshops / consulting: Sencha Touch / Ext JS
Profile on SenchaDevs
www: http://www.nils-dehl.de
twitter: nilsdehl
meetup: Sencha Touch / Ext JS Meetup Frankfurt
videos: http://vimeo.com/album/1621422
conference photos: http://www.flickr.com/photos/nils-dehl/
-
15 Mar 2012 12:13 AM #2
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?
-
15 Mar 2012 12:19 AM #3
Nice...
any chance of transforming this into component structure?
-
15 Mar 2012 1:01 AM #4
trainings / workshops / consulting: Sencha Touch / Ext JS
Profile on SenchaDevs
www: http://www.nils-dehl.de
twitter: nilsdehl
meetup: Sencha Touch / Ext JS Meetup Frankfurt
videos: http://vimeo.com/album/1621422
conference photos: http://www.flickr.com/photos/nils-dehl/
-
15 Mar 2012 1:03 AM #5trainings / workshops / consulting: Sencha Touch / Ext JS
Profile on SenchaDevs
www: http://www.nils-dehl.de
twitter: nilsdehl
meetup: Sencha Touch / Ext JS Meetup Frankfurt
videos: http://vimeo.com/album/1621422
conference photos: http://www.flickr.com/photos/nils-dehl/
-
15 Mar 2012 1:16 AM #6
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.
-
15 Mar 2012 8:45 AM #7
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); } });
-
15 Mar 2012 1:11 PM #8
thanks for the tip with the scrollbar handling,
i added it to my code, like you said it if only to smoothedtrainings / workshops / consulting: Sencha Touch / Ext JS
Profile on SenchaDevs
www: http://www.nils-dehl.de
twitter: nilsdehl
meetup: Sencha Touch / Ext JS Meetup Frankfurt
videos: http://vimeo.com/album/1621422
conference photos: http://www.flickr.com/photos/nils-dehl/
-
19 Mar 2012 1:04 AM #9
Hi,
Have you guys had luck solving the center zoom issue?
-
19 Mar 2012 9:05 AM #10
trainings / workshops / consulting: Sencha Touch / Ext JS
Profile on SenchaDevs
www: http://www.nils-dehl.de
twitter: nilsdehl
meetup: Sencha Touch / Ext JS Meetup Frankfurt
videos: http://vimeo.com/album/1621422
conference photos: http://www.flickr.com/photos/nils-dehl/


Reply With Quote