1 /**
  2  * @fileOverview effect applied when overlay shows or hides
  3  * @author yiminghe@gmail.com
  4  */
  5 KISSY.add("overlay/effect", function (S, Anim, DOM) {
  6     var NONE = 'none'       ,
  7         DURATION = 0.5,
  8         effects = {fade:["Out", "In"], slide:["Up", "Down"]},
  9         displays = ['block', NONE];
 10 
 11     function Effect() {
 12     }
 13 
 14     Effect.ATTRS =
 15     /**
 16      * @leads Overlay#
 17      */
 18     {
 19         /**
 20          * Set v as overlay 's show effect <br>
 21          * v.effect (String): Default:none. can be set as "fade" or "slide" <br>
 22          * v.target (String|KISS.Node): The target node from which overlay should animate from while showing. Since KISSY 1.3.<br>
 23          * v.duration (Number): in seconds. Default:0.5. <br>
 24          * v.easing (String): see {@link Anim.Easing} <br>
 25          * @type Object
 26          */
 27         effect:{
 28             value:{
 29                 effect:'',
 30                 target:null,
 31                 duration:DURATION,
 32                 easing:'easeOut'
 33             },
 34             setter:function (v) {
 35                 var effect = v.effect;
 36                 if (S.isString(effect) && !effects[effect]) {
 37                     v.effect = '';
 38                 }
 39             }
 40 
 41         }
 42     };
 43 
 44     function getGhost(self) {
 45         var el = self.get("el"), $ = S.all;
 46         var ghost = el[0].cloneNode(true);
 47         ghost.style.visibility = "";
 48         ghost.style.overflow = "hidden";
 49         ghost.className += " " + self.get("prefixCls") + "overlay-ghost";
 50         var body;
 51         var elBody
 52         if (elBody = self.get("body")) {
 53             body = DOM.get('.ks-stdmod-body', ghost);
 54             $(body).css({
 55                 height:elBody.height(),
 56                 width:elBody.width()
 57             });
 58             body.innerHTML = "";
 59         }
 60         return $(ghost);
 61     }
 62 
 63     function processTarget(self, show) {
 64 
 65         if (self.__effectGhost) {
 66             self.__effectGhost.stop(1);
 67         }
 68 
 69         var el = self.get("el"),
 70             $ = S.all,
 71             effectCfg = self.get("effect"),
 72             target = $(effectCfg.target),
 73             duration = effectCfg.duration,
 74             targetBox = S.mix(target.offset(), {
 75                 width:target.width(),
 76                 height:target.height()
 77             }),
 78             elBox = S.mix(el.offset(), {
 79                 width:el.width(),
 80                 height:el.height()
 81             }),
 82             from, to,
 83             ghost = getGhost(self),
 84             easing = effectCfg.easing;
 85 
 86 
 87         ghost.insertAfter(el);
 88 
 89         el.hide();
 90 
 91         if (show) {
 92             from = targetBox;
 93             to = elBox;
 94         } else {
 95             from = elBox;
 96             to = targetBox;
 97         }
 98 
 99         ghost.css(from);
100 
101         self.__effectGhost = ghost;
102 
103         ghost.animate(to, {
104             duration:duration,
105             easing:easing,
106             complete:function () {
107                 self.__effectGhost = null;
108                 ghost[0].parentNode.removeChild(ghost[0]);
109                 el.show();
110             }
111         });
112 
113     }
114 
115     function processEffect(self, show) {
116         var el = self.get("el"),
117             effectCfg = self.get("effect"),
118             effect = effectCfg.effect || NONE,
119             target = effectCfg.target;
120 
121         if (effect == NONE && !target) {
122             return;
123         }
124         if (target) {
125             processTarget(self, show);
126             return;
127         }
128         var duration = effectCfg.duration,
129             easing = effectCfg.easing,
130             v = show,
131             index = v ? 1 : 0;
132         // 队列中的也要移去
133         // run complete fn to restore window's original height
134         el.stop(1, 1);
135         var restore = {
136             visibility:"visible",
137             display:displays[index]
138         };
139         el.css(restore);
140         var m = effect + effects[effect][index];
141         el[m](duration, function () {
142             var r2 = {
143                 display:displays[0],
144                 visibility:v ? "visible" : "hidden"
145             };
146             el.css(r2);
147         }, easing);
148     }
149 
150     Effect.prototype = {
151 
152         __bindUI:function () {
153             var self = this
154             self.on("hide", function () {
155                 processEffect(self, 0);
156             });
157             self.on("show", function () {
158                 processEffect(self, 1);
159             });
160         }
161     };
162 
163     return Effect;
164 }, {
165     requires:['anim', 'dom']
166 });