SpriteHand
Module Border
  ResizeBehavior for Atlas
Module Border
Location: BlogsAndy's Blog    
Posted by: host 3/25/2006 10:15 AM

IMPORTANT NOTE: Since the writing of this blog entry, the latest Atlas CTP now includes its own Resize Behavior and Extender! Details and Demo here.

Try It!

If you have played with Microsoft Atlas behaviors,  you might have come across the cool floatingBehavior which allows you to drag and drop web page elements around the screen.

Well, it's also possible to create your own behaviors, and while the documentation on this is pretty much nonexistant, there are two great blog entries here  and here on the subject.

So I thought, floatingBehavior is cool, but what if you could resize elements as well (like a little virtual window)? Thus was born my first Atlas Behavior, resizingBehavior!

Using ResizeBehavior
To add resizing behavior to an element, assuming you have already installed Atlas and created a new Atlas template project... First add ResizeBehavior.js (source at the end of this article) to your Script Manager...

    <atlas:ScriptManager ID="sm" runat="server">

        <Scripts>

            <atlas:ScriptReference ScriptName="AtlasUIDragDrop" />

            <atlas:ScriptReference Path="ScriptLibrary/ResizeBehavior.js" />

        Scripts>

    atlas:ScriptManager>

... next you need to assign the resizeBehavior properties in the XML Config section of your Atlas page...
      resizeControlId should be assigned to the element you want resized
      resizeObjectId should be assigned to the element that controls the resize
      minWidth, minHeight control the minimum resize size
      arrowThreshold allows you to control the sensitivity of resizeObjectId

    <script type="text/xml-script">

       

           

               

                   

                        resizeControlID="resizeTest" resizeObjectID="resizeHandle" minWidth="200" minHeight="100" arrowThreshold="20" />

                       

                   

               

           

       

    script>

ResizeBehavior.js

Type.registerNamespace('SpriteHand.UI');

 

SpriteHand.UI.ResizeBehavior = function() {

    SpriteHand.UI.ResizeBehavior.initializeBase(this);

 

    // Private fields.

    var _resizeControlHandler;

    var _mousedownHandler;

    var _mouseupHandler;

    var _mousemoveHandler;

    var _resizeControlID;          // control that is being resized

    var _resizeControl;

    var _popupBehavior;

    var _mouseIsDown = false;

    var _thresholdArrows = 20;

    var _thresholdMinWidth = 60;

    var _thresholdMinHeight = 40;

    var _isResizing = false;

    var _resizeObjectID;            // control that is used as the resize handle

    var _resizeObject;

 

    var _dragEndHandler;

 

 

    // Properties.

    this.get_resizeControlID = function() {

        return _resizeControlID;

    }

    this.set_resizeControlID = function(value) {

        if(value != _resizeControlID) {

            _resizeControlID = value;

            this.raisePropertyChanged('resizeControlID');

        }

    }

 

    this.get_resizeObjectID = function() {

        return _resizeObjectID;

    }

    this.set_resizeObjectID = function(value) {

        if(value != _resizeObjectID) {

            _resizeObjectID = value;

            this.raisePropertyChanged('resizeObjectID');

        }

    }

 

    this.get_minWidth = function() {

        return _thresholdMinWidth;

    }

    this.set_minWidth = function(value) {

        if(value != _thresholdMinWidth) {

            _thresholdMinWidth = value;

            this.raisePropertyChanged('minWidth');

        }

    }

 

    this.get_minHeight = function() {

        return _thresholdMinHeight;

    }

    this.set_minHeight = function(value) {

        if(value != _thresholdMinHeight) {

            _thresholdMinHeight = value;

            this.raisePropertyChanged('minHeight');

        }

    }

 

    this.get_arrowThreshold = function() {

        return _thresholdArrows;

    }

    this.set_arrowThreshold = function(value) {

        if(value != _thresholdArrows) {

            _thresholdArrows = value;

            this.raisePropertyChanged('arrowThreshold');

        }

    }

 

    // Events.

    this.resizeControlShow = this.createEvent();

 

    // Initialize / Dispose

    this.initialize = function() {

        SpriteHand.UI.ResizeBehavior.callBaseMethod(this, 'initialize');

        _resizeControl = new Sys.UI.Control($(_resizeControlID));

        _resizeObject = new Sys.UI.Control($(_resizeObjectID));

 

        _resizeControl.initialize();

 

        var bounds = Sys.UI.Control.getBounds(_resizeControl.element);

 

        _mousemoveHandler = Function.createDelegate(this, mousemoveHandler);

        document.attachEvent('onmousemove', _mousemoveHandler);

 

        _mousedownHandler = Function.createDelegate(this, mousedownHandler);

        document.attachEvent('onmousedown', _mousedownHandler);

 

        _mouseupHandler = Function.createDelegate(this, mouseupHandler);

        document.attachEvent('onmouseup', _mouseupHandler);

 

        // wire up dragend event with drag handler

        _dragEndHandler = Function.createDelegate(this, dragEndHandler);

        _resizeControl.element.attachEvent("ondragend", _dragEndHandler);

 

        // disable text selection (ie only)

        document.onselectstart = function() {return false;}

 

 

    }

 

    this.dispose = function() {

        SpriteHand.UI.ResizeBehavior.callBaseMethod(this, 'dispose');

 

        document.detachEvent('onmousedown', _mousedownHandler);

        document.detachEvent('onmouseup', _mouseupHandler);

        document.detachEvent('onmousemove', _mousemoveHandler);

 

        _mousemoveHandler = null;

        _mousedownHandler = null;

        _mouseupHandler = null;

    }

 

    // Handlers.

    function dragEndHandler() {

        window.status="dragEndHandler";

        _mouseIsDown = false

        _isResizing = false;

    }

 

    function mousedownHandler() {

        _mouseIsDown = true;

    }

 

    function mouseupHandler() {

        _mouseIsDown = false

        _isResizing = true;

    }

 

    function mousemoveHandler() {

        window.status="";

 

        var boundsDragHandle = Sys.UI.Control.getBounds(_resizeObject.element);

        var bounds = Sys.UI.Control.getBounds(_resizeControl.element);

 

        var x = window.event.clientX;

        var y = window.event.clientY;

 

        if (!_mouseIsDown) {

            // check for resize east

            if( (x >= (boundsDragHandle.x - _thresholdArrows) && x <= (boundsDragHandle.x + boundsDragHandle.width + _thresholdArrows)) &&

                (y >= (boundsDragHandle.y - _thresholdArrows) && y <= (boundsDragHandle.y + boundsDragHandle.height + _thresholdArrows))) {

                _resizeControl.element.style.cursor="se-resize";

                _isResizing = true;

                window.status="click and drag to resize southeast";

 

            } else {

                _resizeControl.element.style.cursor="auto";

            }

        }       

        if (_mouseIsDown && _isResizing) {

 

            newWidth = (x + _resizeObject.element.style.width) - bounds.x;

            if (newWidth > _thresholdMinWidth) _resizeControl.element.style.width = newWidth + "px";

 

            newHeight = (y + _resizeObject.element.style.height) - bounds.y;

            if (newHeight > _thresholdMinHeight) _resizeControl.element.style.height = newHeight + "px";

        }

 

 

    }

 

    // Public methods.

 

    // getDescriptor.

    this.getDescriptor = function() {

        var td = SpriteHand.UI.ResizeBehavior.callBaseMethod(this, 'getDescriptor');

 

        td.addProperty('resizeControlID', String);

        td.addProperty('resizeObjectID', String);

        td.addProperty('minWidth', Number);

        td.addProperty('minHeight', Number);

        td.addProperty('arrowThreshold', Number);

 

        return td;

    }

}

SpriteHand.UI.ResizeBehavior.registerClass('SpriteHand.UI.ResizeBehavior', Sys.UI.Behavior);

Sys.TypeDescriptor.addType('script', 'resizeBehavior', SpriteHand.UI.ResizeBehavior);

Permalink |  Trackback

Comments (9)   Add Comment
Re: ResizeBehavior for Atlas    By Anonymous on 5/10/2006 5:52 AM
When I added this behaviour, I get an "unrecognised tag script: resizeBehavior" error message.

I have looked at the source for your demo, as well as this code, and can't spot what I am doing wrong. Please help!

Re: ResizeBehavior for Atlas    By Anonymous on 5/10/2006 6:11 AM
Did you make sure you put ResizeBehavior.js in the ScriptLibrary subdirectory of your webroot? And then make sure the relative path in your ScriptManager is...



Issue with Right Click    By Anonymous on 5/21/2006 4:19 PM
Andy, great job with the behavior. If you right click anywhere on the page, the element gets resized to wherever the right click was performed.

Re: ResizeBehavior for Atlas    By Anonymous on 6/15/2006 12:55 PM
There is a problem when you click anywhere on the page and then click and drag. Since _isResizing is being set to true on mouseup this is causing the control to resize wherever you click. To fix this replace the mousemoveHandler and mousedownHandler with these 2 methods.

function mousemoveHandler() {
if (_mouseIsDown) {
var x = window.event.clientX;
var y = window.event.clientY;
var bounds = Sys.UI.Control.getBounds(_resizeControl.element);
newWidth = (x + _resizeObject.element.style.width) - bounds.x;
if (newWidth > _thresholdMinWidth) _resizeControl.element.style.width = newWidth + "px";

newHeight = (y + _resizeObject.element.style.height) - bounds.y;
if (newHeight > _thresholdMinHeight) _resizeControl.element.style.height = newHeight + "px";
}
}


function mousedownHandler() {
var x = window.event.clientX;
var y = window.event.clientY;
var boundsDragHandle = Sys.UI.Control.getBounds(_resizeObject.element);
if( (x >= (boundsDragHandle.x - _thresholdArrows) && x <= (boundsDragHandle.x + boundsDragHandle.width + _thresholdArrows)) &&
(y >= (boundsDragHandle.y - _thresholdArrows) && y <= (boundsDragHandle.y + boundsDragHandle.height + _thresholdArrows))) {
_resizeControl.element.style.cursor="se-resize";
_mouseIsDown = true;
} else {
_resizeControl.element.style.cursor="auto";
}
}

Re: ResizeBehavior for Atlas    By Anonymous on 7/12/2006 3:23 AM
Thanks. I was able to implement resizing using XML config section. Although if i try to perform the same operation using function addResizingBehavior it does not work.

function addResizingBehavior(ctrl, ctrlHandle){
var resizingBehavior = new AtlasNotes.UI.ResizeBehavior();
resizingBehavior.set_resizeControlID(ctrl);
resizingBehavior.set_resizeObjectID(ctrlHandle);
resizingBehavior.set_minWidth("200");
resizingBehavior.set_minHeight("100");
resizingBehavior.set_arrowThreshold("20");
var resizeItem = new Sys.UI.Control(ctrl);
resizeItem.get_behaviors().add(resizingBehavior);
resizingBehavior.initialize();
}

By adding a function I can dynamically attach the behavior to a control.

Re: ResizeBehavior for Atlas    By Anonymous on 7/18/2006 8:44 AM
Hello,

I was testing the Resize Behavior, but I do have found some problems like:

First of all, I had the same problem described above on the click everywhere in the page, but I then override the mousemoveHandler and mousedownHandler with the new ones and everything went good.

On the other hand In many versions of IE6 I can't resize. But the most important I can't select any text on the page (do you understand what I mean), not even using the keyboard (Firefox works fine). But the company I'm developing for uses only IE6 even worst, the most machines are win98 based.

For the application I'm developing it is essential to resize certain part of the page, so if you could help me, I'll appreciate a lot.

It is possible only to resize the horizontal, not both at the same time?

thanks

Re: ResizeBehavior for Atlas    By Anonymous on 7/18/2006 9:01 AM
Hi, thanks for the feedback.

First a disclaimer - this Resize Behavior was meant only as a sample behavior and I hope to have time to refine it, there is much to add!

If you want to enable text selection, you can do so by removing this code from the behavior:

// disable text selection (ie only)

document.onselectstart = function() {return false;}

... but note that you will likely run into funky problems with text being selected as you resize. There may be a way around this - perhaps by disabling document text selection only in the resize event.

Can you tell me what you mean by "in many versions of IE6 I can't resize" ? Do you mean in Windows 98?

Re: ResizeBehavior for Atlas    By Anonymous on 7/18/2006 10:40 AM
Hello

we have here many computers running differente version of operating systems from win98, win2000, winxp, etc all running ie6 and I noticed that in some ie6 releases the resize doesn't work.

for example ie6 without sp1 doesn't resize, in XP w/o sp2 doesn't resize. and so.

about the funky problems you talked about, I guess I solved that using a divider inside a
and setting the arrowtrehshold to 1, so only over the divider i can resize.

I'll solve the disable text selection and tell you what happend.

thanks


Re: ResizeBehavior for Atlas    By Anonymous on 7/18/2006 10:55 AM
Now Everything goes fine.

As you mentioned there was impossible to resize if there are anything contained in the div I want to resize, so I applied the
over the divider I use to resize and now is perfect.

thanks a lot, I'll check this blog contantly in case you make any change regarding only to resize the horizotal

Bye


Title:
Comment:
Add Comment   Cancel 
Module Border Module Border
Module Border
  Blog_List
Module Border
Module Border Module Border
Module Border
  Subscribe
Module Border

RSS

Module Border Module Border
Module Border
  Diversions
Module Border

DESTROY ALL INVADERS
A scrolling shooter game where the objective is to destroy the invading UFO's flying over a neighborhood of your choosing. Imagery provided by Microsoft Virtual Earth. Created using Silverlight 2.
PLAY IT

INFO AND CODE



HOOK SHOT
This little basketball game was submitted as an entry to the TeamZoneSports Silverlight Contest. Created using Silverlight 2 and the Farseer Physics engine.
PLAY IT

INFO AND CODE



SORT THE FOOBARS
A game where you need to sort the good foobars from the bad ones. Created using Silverlight 2 and the Farseer Physics engine.
PLAY IT

MORE INFO



POLYGON PHYSICS DEMO
A demo showing polygon physics where the user draws physics objects with the mouse. Created using Silverlight 2 and the Farseer Physics engine.
PLAY IT

MORE INFO



SILVERLIGHT ROCKS!
Destroy the asteroids before they destroy your ship! Created using Silverlight 2.
PLAY IT

INFO AND CODE



FISH GAME
A simple game of harpoon-the-fish. Written using the AJAX Sprite Toolkit.
PLAY IT

INFO AND CODE

Module Border Module Border
Module Border
  Search_Blog
Module Border
Module Border Module Border
Module Border
  Blog_Archive
Module Border
Module Border Module Border
Copyright (c) 2008 andy.beaulieu.com - Login