PDA

View Full Version : Best approach to display a "floating" image inside a Window



ffanf
9 Jul 2012, 7:55 AM
Hi,

First post here, I'd like to thank Sencha team for their great work. I'm a total beginner with Sencha, I recently started to migrate a user interface from regular html/php/smarty to Sencha/php (using REST) (it will be a huge improvement in user-friendlyness).

I'm a little bit stuck right now, and don't know what should be the best approach to display a "zoomed" picture.
What I would like to achieve is pretty simple, by default picture is displayed fitted to its container size, and if user decided to "zoom", I want the picture to be displayed with the selected zoom level but without increasing window (or container) size, then user can use their mouse to drag the picture around and look into it in detail.

Screenshots might help you to understand what I'm trying to achieve.
This is the default display, the picture in the middle is automatically resized to fit its container size.
36958

What I'm trying to achieve is that if user decide to zoom, picture size will become bigger than the area displayed. Then users should be able to move within the picture by dragging it around.
Below is an example if I set picture size bigger than the size of its container.
36959

Where I'm stuck is how to make the picture draggable/floatable inside its container.

Container located between "Previous/Next" buttons and thumbnails.


Ext.define('Webcampak.view.pictures.CurrentPicture' ,{
extend: 'Ext.container.Container',
alias : 'widget.currentpicture',
style: 'text-align: center',
items: [{
xtype: 'image',
itemId: 'picturedisplay',
src: 'https://mywebsite.com/somedirectory/webcam-1280x720.jpg',
}, {
itemId: 'picturedate',
cls: 'viewpicturessourcename',
html: 'Current date',
}],
});


Size of the picture is defined within the controller:


//Get picture details
currentPictureValue = this.getPicturesViewPictureStore().last();
var currentPictureFile = currentPictureValue.getData()['picture'];
var currentPictureWidth = currentPictureValue.getData()['picturewidth'];
var currentPictureHeight = currentPictureValue.getData()['pictureheight'];
var currentPictureSourceId = currentPictureValue.getData()['sourceid'];

/Get window size (to accelerate loading by only getting picture with same width as window). For Height, 30px adjustement is to keep date below picture on screen
var currentWindowWidth = this.getPictureswindow().getComponent('globalpanel').getComponent('centralpanel').getComponent('picturepanel').getWidth();
var currentWindowHeight = this.getPictureswindow().getComponent('globalpanel').getComponent('centralpanel').getComponent('picturepanel').getHeight() - 30;
console.log('Log: Controller->Pictures->Pictures: onPictureHourSelected: Main Picture: Window Size:' + currentWindowWidth + 'x' + currentWindowHeight);
console.log('Log: Controller->Pictures->Pictures: onPictureHourSelected: Main Picture: Picture Size:' + currentPictureWidth + 'x' + currentPictureHeight);


//We ensure that target height of the picture will not by greather than current window height (otherwise a portion of the picture will not be displayed)
currentPictureTargetHeight = currentWindowWidth * currentPictureHeight / currentPictureWidth;
currentPictureTargetWidth = currentWindowWidth;
this.getCurrentpicture().getComponent('picturedisplay').setSize({width:currentWindowWidth, height:currentPictureTargetHeight});


//Picture will be accessed via timthumb, width is passed as an argument
this.getCurrentpicture().getComponent('picturedisplay').setSrc(currentPictureFile + '&w=' + currentPictureTargetWidth);


For the second screenshot, I simply replaced


this.getCurrentpicture().getComponent('picturedisplay').setSize({width:currentWindowWidth, height:currentPictureTargetHeight});

with:


this.getCurrentpicture().getComponent('picturedisplay').setSize({width:currentWindowWidth*2, height:currentPictureTargetHeight*2});

to simulate a 2x zoom to increase size of the picture (until zoom feature is implemented).

I thought it would just be a matter of declaring the image flotable


Ext.define('Webcampak.view.pictures.CurrentPicture' ,{
extend: 'Ext.container.Container',
alias : 'widget.currentpicture',
style: 'text-align: center',
items: [{
xtype: 'image',
floating: true,
itemId: 'picturedisplay',
src: 'https://s001.webcampak.com/sources/source12/live/webcam-1280x720.jpg',
}, {
itemId: 'picturedate',
cls: 'viewpicturessourcename',
html: 'Current date',
}],
})


But if I do that, apparently "picturedisplay" component disappear (so I cannot use setSize, setSrc anymore and get "Uncaught TypeError: Cannot call method 'setSize' of undefined" error).

If I understand properly, I'm supposed to "show" it (from within the controller ?) (Floating components do not participate in the Container's layout. Because of this, they are not rendered until you explicitly show (http://docs.sencha.com/ext-js/4-0/#!/api/Ext.Component-event-show) them.)

But I don't fully understand how this could be done, I'm sure the answer is very simple but I'm stuck right now :)

Thanks a lot for your help.

sdt6585
9 Jul 2012, 1:38 PM
Something like this?
http://jsfiddle.net/sdt6585/w6GwM/72/embedded/result/ (http://jsfiddle.net/sdt6585/w6GwM/72/embedded/result/)

If you need to do it without the scroll bars, I would suggest catching the mousedown and mouseup on the image, and mousemove event on the document then changing the top and left properties of the image to reflect the change in mouse movement while the button is still down.

ffanf
9 Jul 2012, 2:15 PM
Thanks, that's very similar to what I wanted to do.

In parallel I used another approach and inserted jquery with jqzoom (http://www.mind-projects.it/projects/jqzoom/demos.php) and it works pretty well and do exactly what I wanted to do.

I added this into the controller:


//Loading jqzoom to display zoomed picture
console.log('Log: Controller->Pictures->Pictures: onPictureHourSelected: Load jqzoom module');
var options = {
zoomType: 'innerzoom',
lens:true,
preloadImages: true,
alwaysOn:false
};
$(".jqzoom").jqzoom(options);


Then followed jqzoom instructions.

I don't know yet if I'll stick on jqzoom or move to your suggestion, but thanks a lot.

sdt6585
9 Jul 2012, 2:19 PM
I would stick with what's working personally unless that's the only place you're using the jQuery framework.

If you do decide to roll your own, this might be a useful reference point:
http://luke.breuer.com/tutorial/javascript-drag-and-drop-tutorial.aspx

(http://luke.breuer.com/tutorial/javascript-drag-and-drop-tutorial.aspx)Good luck.