You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

216 lines
5.5 KiB
JavaScript

/**
* @class Ext.ux.Spotlight
* UX used to provide a spotlight around a specified component/element.
*/
Ext.define('Ext.ux.Spotlight', {
/**
* @private
* The baseCls for the spotlight elements
*/
baseCls: 'x-spotlight',
/**
* @cfg animate {Boolean} True to animate the spotlight change
* (defaults to true)
*/
animate: true,
/**
* @cfg duration {Integer} The duration of the animation, in milliseconds
* (defaults to 250)
*/
duration: 250,
/**
* @cfg easing {String} The type of easing for the spotlight animatation
* (defaults to null)
*/
easing: null,
/**
* @private
* True if the spotlight is active on the element
*/
active: false,
constructor: function(config){
Ext.apply(this, config);
},
/**
* Create all the elements for the spotlight
*/
createElements: function() {
var me = this,
baseCls = me.baseCls,
body = Ext.getBody();
me.right = body.createChild({
cls: baseCls
});
me.left = body.createChild({
cls: baseCls
});
me.top = body.createChild({
cls: baseCls
});
me.bottom = body.createChild({
cls: baseCls
});
me.all = Ext.create('Ext.CompositeElement', [me.right, me.left, me.top, me.bottom]);
},
/**
* Show the spotlight
*/
show: function(el, callback, scope) {
var me = this;
//get the target element
me.el = Ext.get(el);
//create the elements if they don't already exist
if (!me.right) {
me.createElements();
}
if (!me.active) {
//if the spotlight is not active, show it
me.all.setDisplayed('');
me.active = true;
Ext.EventManager.onWindowResize(me.syncSize, me);
me.applyBounds(me.animate, false);
} else {
//if the spotlight is currently active, just move it
me.applyBounds(false, false);
}
},
/**
* Hide the spotlight
*/
hide: function(callback, scope) {
var me = this;
Ext.EventManager.removeResizeListener(me.syncSize, me);
me.applyBounds(me.animate, true);
},
/**
* Resizes the spotlight with the window size.
*/
syncSize: function() {
this.applyBounds(false, false);
},
/**
* Resizes the spotlight depending on the arguments
* @param {Boolean} animate True to animate the changing of the bounds
* @param {Boolean} reverse True to reverse the animation
*/
applyBounds: function(animate, reverse) {
var me = this,
box = me.el.getBox(),
//get the current view width and height
viewWidth = Ext.Element.getViewWidth(true),
viewHeight = Ext.Element.getViewHeight(true),
i = 0,
config = false,
from, to, clone;
//where the element should start (if animation)
from = {
right: {
x: box.right,
y: viewHeight,
width: (viewWidth - box.right),
height: 0
},
left: {
x: 0,
y: 0,
width: box.x,
height: 0
},
top: {
x: viewWidth,
y: 0,
width: 0,
height: box.y
},
bottom: {
x: 0,
y: (box.y + box.height),
width: 0,
height: (viewHeight - (box.y + box.height)) + 'px'
}
};
//where the element needs to finish
to = {
right: {
x: box.right,
y: box.y,
width: (viewWidth - box.right) + 'px',
height: (viewHeight - box.y) + 'px'
},
left: {
x: 0,
y: 0,
width: box.x + 'px',
height: (box.y + box.height) + 'px'
},
top: {
x: box.x,
y: 0,
width: (viewWidth - box.x) + 'px',
height: box.y + 'px'
},
bottom: {
x: 0,
y: (box.y + box.height),
width: (box.x + box.width) + 'px',
height: (viewHeight - (box.y + box.height)) + 'px'
}
};
//reverse the objects
if (reverse) {
clone = Ext.clone(from);
from = to;
to = clone;
}
if (animate) {
Ext.Array.forEach(['right', 'left', 'top', 'bottom'], function(side) {
me[side].setBox(from[side]);
me[side].animate({
duration: me.duration,
easing: me.easing,
to: to[side]
});
},
this);
} else {
Ext.Array.forEach(['right', 'left', 'top', 'bottom'], function(side) {
me[side].setBox(Ext.apply(from[side], to[side]));
me[side].repaint();
},
this);
}
},
/**
* Removes all the elements for the spotlight
*/
destroy: function() {
var me = this;
Ext.destroy(me.right, me.left, me.top, me.bottom);
delete me.el;
delete me.all;
}
});