dojo.provide("dojox.fx.Shadow"); dojo.experimental("dojox.fx.Shadow"); dojo.require("dijit._Widget"); dojo.require("dojo.NodeList-fx"); dojo.declare("dojox.fx.Shadow", dijit._Widget,{ // summary: Adds a drop-shadow to a node. // // example: // | // add drop shadows to all nodes with class="hasShadow" // | dojo.query(".hasShadow").forEach(function(n){ // | var foo = new dojox.fx.Shadow({ node: n }); // | foo.startup(); // | }); // // shadowPng: String // Base location for drop-shadow images shadowPng: dojo.moduleUrl("dojox.fx", "resources/shadow"), // shadowThickness: Integer // How wide (in px) to make the shadow shadowThickness: 7, // shadowOffset: Integer // How deep to make the shadow appear to be shadowOffset: 3, // opacity: Float // Overall opacity of the shadow opacity: 0.75, // animate: Boolean // A toggle to disable animated transitions animate: false, // node: DomNode // The node we will be applying this shadow to node: null, startup: function(){ // summary: Initializes the shadow. this.inherited(arguments); this.node.style.position = "relative"; // make all the pieces of the shadow, and position/size them as much // as possible (but a lot of the coordinates are set in sizeShadow this.pieces={}; var x1 = -1 * this.shadowThickness; var y0 = this.shadowOffset; var y1 = this.shadowOffset + this.shadowThickness; this._makePiece("tl", "top", y0, "left", x1); this._makePiece("l", "top", y1, "left", x1, "scale"); this._makePiece("tr", "top", y0, "left", 0); this._makePiece("r", "top", y1, "left", 0, "scale"); this._makePiece("bl", "top", 0, "left", x1); this._makePiece("b", "top", 0, "left", 0, "crop"); this._makePiece("br", "top", 0, "left", 0); this.nodeList = dojo.query(".shadowPiece",this.node); this.setOpacity(this.opacity); this.resize(); }, _makePiece: function(name, vertAttach, vertCoord, horzAttach, horzCoord, sizing){ // summary: append a shadow pieces to the node, and position it var img; var url = this.shadowPng + name.toUpperCase() + ".png"; if(dojo.isIE < 7){ img = dojo.create("div"); img.style.filter="progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+url+"'"+ (sizing?", sizingMethod='"+sizing+"'":"") + ")"; }else{ img = dojo.create("img", { src:url }); } img.style.position="absolute"; img.style[vertAttach]=vertCoord+"px"; img.style[horzAttach]=horzCoord+"px"; img.style.width=this.shadowThickness+"px"; img.style.height=this.shadowThickness+"px"; dojo.addClass(img,"shadowPiece"); this.pieces[name]=img; this.node.appendChild(img); }, setOpacity: function(/* Float */n,/* Object? */animArgs){ // summary: set the opacity of the underlay // note: does not work in IE? FIXME. if(dojo.isIE){ return; } if(!animArgs){ animArgs = {}; } if(this.animate){ var _anims = []; this.nodeList.forEach(function(node){ _anims.push(dojo._fade(dojo.mixin(animArgs,{ node: node, end: n }))); }); dojo.fx.combine(_anims).play(); }else{ this.nodeList.style("opacity",n); } }, setDisabled: function(/* Boolean */disabled){ // summary: enable / disable the shadow if(disabled){ if(this.disabled){ return; } if(this.animate){ this.nodeList.fadeOut().play(); }else{ this.nodeList.style("visibility","hidden"); } this.disabled = true; }else{ if(!this.disabled){ return; } if(this.animate){ this.nodeList.fadeIn().play(); }else{ this.nodeList.style("visibility","visible"); } this.disabled = false; } }, resize: function(/* dojox.fx._arg.ShadowResizeArgs */args){ // summary: Resizes the shadow based on width and height. var x; var y; if(args){ x = args.x; y = args.y; }else{ var co = dojo._getBorderBox(this.node); x = co.w; y = co.h; } var sideHeight = y - (this.shadowOffset+this.shadowThickness); if (sideHeight < 0) { sideHeight = 0; } if (y < 1) { y = 1; } if (x < 1) { x = 1; } with(this.pieces){ l.style.height = sideHeight+"px"; r.style.height = sideHeight+"px"; b.style.width = x+"px"; bl.style.top = y+"px"; b.style.top = y+"px"; br.style.top = y+"px"; tr.style.left = x+"px"; r.style.left = x+"px"; br.style.left = x+"px"; } } });