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 });