View Full Version : Scrollable Viewport (similar to Google Maps)

15 Jul 2012, 9:29 PM

I have created an outer container and an inner container. The idea is to make the outer container the 'viewport' and the inner container be the content, in a draggable/scrollable way, like how Google Maps does it.

I am encountering two issues...

1) I set the outer container to layout: absolute and the inner container's width and height both to 10000, and the outer container's autoScroll to true (auto?) That way, the containers should render and there will be horizontal and vertical scrollbars. What is happening is I am only getting a vertical scrollbar which does scale to the 10000 pixel size. There is no horizontal scrollbar.

So I used CSS instead and set overflow: scroll for the outer container. This does help, but the horizontal scrollbar does not scale the same way the vertical one does. I checked the DOM and the width of 10000 is actually more like 1500, meaning that my CSS is not being honored.

2) I added some basic drag/drop code to make the viewport scrollable to get something going:

var draggable = Ext.create('Ext.dd.DD', innerContainer.getEl(), 'ddGroup');draggable.onMouseDown = function(e) {
draggable.onMouseUp = function(e) {
draggable.onDrag = function(e) {
console.log('onDrag [' + e.getX() + ',' + e.getY() + ']');

This does create a draggable inner container, but, I cannot drag the object to the left. In other words, X and Y cannot be less than 0. I would need to make it scrollable in any direction.

Any help would be appreciated!

16 Jul 2012, 9:34 PM
I managed to figure out the scrolling constraints (issue #2 above). I changed the alignElWithMouse function in Ext.dd.DD to remove the Math.max() wrappers when setting the element's position:

alignElWithMouse: function(el, iPageX, iPageY) {
var oCoord = this.getTargetCoord(iPageX, iPageY),
fly = el.dom ? el : Ext.fly(el, '_dd'),
elSize = fly.getSize(),
EL = Ext.Element,

if (!this.deltaSetXY) {
vpSize = this.cachedViewportSize = { width: EL.getDocumentWidth(), height: EL.getDocumentHeight() };
aCoord = [
Math.max(0, Math.min(oCoord.x, vpSize.width - elSize.width)),
Math.max(0, Math.min(oCoord.y, vpSize.height - elSize.height))
newLeft = fly.getLocalX();
newTop = fly.getLocalY();
this.deltaSetXY = [newLeft - oCoord.x, newTop - oCoord.y];
} else {
vpSize = this.cachedViewportSize;
//Math.max(0,Math.min(oCoord.x + this.deltaSetXY[0], vpSize.width - elSize.width)),
//Math.max(0,Math.min(oCoord.y + this.deltaSetXY[1], vpSize.height - elSize.height))
Math.min(oCoord.x + this.deltaSetXY[0], vpSize.width - elSize.width),
Math.min(oCoord.y + this.deltaSetXY[1], vpSize.height - elSize.height)

this.cachePosition(oCoord.x, oCoord.y);
this.autoScroll(oCoord.x, oCoord.y, el.offsetHeight, el.offsetWidth);
return oCoord;