PDA

View Full Version : [CLOSED][3.0]Height not working with scale()



fzammetti
8 Apr 2009, 12:21 PM
Hi folks... using the latest v3 code, the following example does not properly animate the height of a Window using scale()... I'm assuming this is something that should work, please tell me if that's incorrect. Otherwise, have a look:


<html>
<head>
<link rel="stylesheet" type="text/css" href="ext/resources/css/ext-all.css">
<script type="text/javascript" src="ext/adapter/ext/ext-base.js"></script>
<script type="text/javascript" src="ext/ext-all-debug.js"></script>
<script>
Ext.onReady(function() {
new Ext.Window({
id : "myWin", html : "test", width : 200, height : 200,
buttons : [
{
xtype : "button", text : "expand",
handler : function() {
Ext.get("myWin").scale(200, 400, {duration : 1 });
}
}
]
}).show();
});
</script>
</head>
<body></body>
</html>Note that the width DOES scale properly if you change the scale value, just height doesn't. More interestingly, the height of the shadow actually seems to scale properly, just not animated, but the Window itself is not.

Thanks,
Frank

aconran
8 Apr 2009, 12:34 PM
Frank -

Animations are meant to be used on Ext.Element's not Ext.Components.

When you create any component Ext JS creates the top element with the same id as the component. When you use Ext.get you are retrieving an Ext.Element. When you use Ext.getCmp you are retrieving an Ext.Component (in this case an Ext.Window). Components are higher level UI components like Window, TabPanel, GridPanel. Components consist of many pieces of markup and elements.

Because we give our elements the same id your Ext.get retrieves the proper element. You cannot use animation effects on Components without a little bit of underlying work. Check out our animation methods (animShow & animHide) in the source code of Window to see other things you must manage such as animating a proxy rather than the real element, syncing the shadows, etc.

Animal
8 Apr 2009, 12:39 PM
It does seem that Ext.lib.Anim is broken in 3.0.

But you can't just set the size of a Window's element. There's more to a Window than that.

You must use this override:



Ext.override(Ext.Window, {
defaultScaleCfg: {
duration: .25,
easing: 'easeNone'
},

scale: function(w, h) {
var a = Ext.lib.Anim.motion(this.el, Ext.apply({
height: {to: h},
width: {to: w}
}, this.scaleCfg, this.defaultScaleCfg));
a.onTween.addListener(function(){
if (this.fixedCenter) {
this.center();
}
this.syncSize();
this.syncShadow();
}, this);
a.animate();
}
});


I tested this override in the "hello world" Window example, and it works in Ext 2.0, but not in 3.0, so the Ext.lib.Anim has stopped working has a slightly different API.

fzammetti
8 Apr 2009, 2:46 PM
Animations are meant to be used on Ext.Element's not Ext.Components.

When you create any component Ext JS creates the top element with the same id as the component. When you use Ext.get you are retrieving an Ext.Element. When you use Ext.getCmp you are retrieving an Ext.Component (in this case an Ext.Window). Components are higher level UI components like Window, TabPanel, GridPanel. Components consist of many pieces of markup and elements.


Right, I know all of that... that's why I used Ext.get() rather than Ext.getCmp()

Even knowing that though, I think I was expecting that Ext would properly scale the Window if I simply scaled it's element returned by Ext.get()... but...



Because we give our elements the same id your Ext.get retrieves the proper element. You cannot use animation effects on Components without a little bit of underlying work. Check out our animation methods (animShow & animHide) in the source code of Window to see other things you must manage such as animating a proxy rather than the real element, syncing the shadows, etc.

...that makes sense, and given that I think it enforces that my expectation was incorrect (I guess I figured Ext is so damned clever everywhere else that maybe it would be clever enough to handle all the details of scaling a Window).

I guess the fact that the width is affected as expected by scale() is really just a bit of luck... kind of makes sense if I imagine that the Window is constructed along the lines of an outer <div> and one or more inner <div>'s for its content, and the inner <div>s are width:100% and it's the outer <div> that gets scaled, then seeing the width work and the height not work I think makes sense.

@Animal, thanks for the override... if whoever winds up fixing Ext.lib.anim could post to this thread when it's checked in I'd very much appreciate it so I can grab the latest and use this override... my team kind of set an expectation about a certain UI feature that hinges on this working :)

Thanks guys,
Frank

mjlecomte
8 Apr 2009, 6:42 PM
Frank, the thread was closed. Animal's report is a different issue. Perhaps you want to open another thread.

Animal
8 Apr 2009, 11:27 PM
The working Ext 3.0 version of Window.scale is



scale: function(w, h, duration, easing) {
var me = this, a = Ext.lib.Anim.motion(this.el, {
height: {to: h},
width: {to: w}
}, duration || 0.35, easing || 'easeOut', function(){
me.width = w;
me.height = h;
a.onTween.clearListeners();
});
a.onTween.addListener(function(){
if (me.fixedCenter) {
me.center();
}
me.syncSize();
me.syncShadow();
});
a.animate();
return me;
}

mjlecomte
22 Apr 2009, 4:46 AM
A couple threads have popped up on this. A few things I noticed when I was testing:

after the animation try resizing the window, the shadow is screwed up.
use code below, getSize() seems to be correct, but the window's set "width" and "height" parameters are still the original size.



Ext.override(Ext.BoxComponent, {

scale: function(w, h, duration, easing){
/*
motion: function(el, args, duration, easing, cb, scope){
return this.run(el, args, duration, easing, cb, scope, EXTLIB.Motion);
},
*/
var callback = function(){
a.onTween.clearListeners();
}

var a = Ext.lib.Anim.motion(
this.el,
{
height: {to: h},
width: {to: w}
},
duration || 0.35,
easing || 'easeOut',
callback
);
a.onTween.addListener(function(){
if (this.fixedCenter) {
this.center();
}
this.syncSize();
this.syncShadow();
}, this);

a.onComplete.addListener(function(){
a.onTween.clearListeners();
console.info('complete');
console.info(this.getSize()); // size is 300x200
console.info(this); // size is 150x50
}, this, {
single: true
});

a.animate();
}
});

Ext.onReady(function(){

var scale = function () {
win.scale(300, 200, 4);
}
win = new Ext.Window({
fixedCenter: true,
html: "test",
width: 150,
height: 50,
buttons: [{
text: "scale",
handler: scale
}]
}).show();

});

Animal
23 Apr 2009, 2:45 AM
http://extjs.com/forum/showthread.php?p=314649#post314649 edited to set size on completion.

mjlecomte
23 Apr 2009, 8:06 AM
This thread is academic for me mind you.

Did you try resizing the window after the effect is complete? The height of the shadow is whacked.

Something is amiss. If you set a breakpoint in Layer.sync() you can see the offsetHeight never gets updated:



sync : function(doShow){
var sw = this.shadow;
if(!this.updating && this.isVisible() && (sw || this.useShim)){
var sh = this.getShim();

var w = this.getWidth(),
h = this.getHeight();
console.info('==>this.dom.offsetHeight:',this.dom.offsetHeight);
console.info('Layer sync, wxh:', w,'x',h); // once scale() is run the height won't update
var l = this.getLeft(true),