effect-size.js (5315B)
1 /*! 2 * jQuery UI Effects Size 1.12.1 3 * http://jqueryui.com 4 * 5 * Copyright jQuery Foundation and other contributors 6 * Released under the MIT license. 7 * http://jquery.org/license 8 */ 9 10 //>>label: Size Effect 11 //>>group: Effects 12 //>>description: Resize an element to a specified width and height. 13 //>>docs: http://api.jqueryui.com/size-effect/ 14 //>>demos: http://jqueryui.com/effect/ 15 16 ( function( factory ) { 17 if ( typeof define === "function" && define.amd ) { 18 19 // AMD. Register as an anonymous module. 20 define( [ 21 "jquery", 22 "./effect" 23 ], factory ); 24 } else { 25 26 // Browser globals 27 factory( jQuery ); 28 } 29 }( function( $ ) { 30 31 return $.effects.define( "size", function( options, done ) { 32 33 // Create element 34 var baseline, factor, temp, 35 element = $( this ), 36 37 // Copy for children 38 cProps = [ "fontSize" ], 39 vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ], 40 hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ], 41 42 // Set options 43 mode = options.mode, 44 restore = mode !== "effect", 45 scale = options.scale || "both", 46 origin = options.origin || [ "middle", "center" ], 47 position = element.css( "position" ), 48 pos = element.position(), 49 original = $.effects.scaledDimensions( element ), 50 from = options.from || original, 51 to = options.to || $.effects.scaledDimensions( element, 0 ); 52 53 $.effects.createPlaceholder( element ); 54 55 if ( mode === "show" ) { 56 temp = from; 57 from = to; 58 to = temp; 59 } 60 61 // Set scaling factor 62 factor = { 63 from: { 64 y: from.height / original.height, 65 x: from.width / original.width 66 }, 67 to: { 68 y: to.height / original.height, 69 x: to.width / original.width 70 } 71 }; 72 73 // Scale the css box 74 if ( scale === "box" || scale === "both" ) { 75 76 // Vertical props scaling 77 if ( factor.from.y !== factor.to.y ) { 78 from = $.effects.setTransition( element, vProps, factor.from.y, from ); 79 to = $.effects.setTransition( element, vProps, factor.to.y, to ); 80 } 81 82 // Horizontal props scaling 83 if ( factor.from.x !== factor.to.x ) { 84 from = $.effects.setTransition( element, hProps, factor.from.x, from ); 85 to = $.effects.setTransition( element, hProps, factor.to.x, to ); 86 } 87 } 88 89 // Scale the content 90 if ( scale === "content" || scale === "both" ) { 91 92 // Vertical props scaling 93 if ( factor.from.y !== factor.to.y ) { 94 from = $.effects.setTransition( element, cProps, factor.from.y, from ); 95 to = $.effects.setTransition( element, cProps, factor.to.y, to ); 96 } 97 } 98 99 // Adjust the position properties based on the provided origin points 100 if ( origin ) { 101 baseline = $.effects.getBaseline( origin, original ); 102 from.top = ( original.outerHeight - from.outerHeight ) * baseline.y + pos.top; 103 from.left = ( original.outerWidth - from.outerWidth ) * baseline.x + pos.left; 104 to.top = ( original.outerHeight - to.outerHeight ) * baseline.y + pos.top; 105 to.left = ( original.outerWidth - to.outerWidth ) * baseline.x + pos.left; 106 } 107 element.css( from ); 108 109 // Animate the children if desired 110 if ( scale === "content" || scale === "both" ) { 111 112 vProps = vProps.concat( [ "marginTop", "marginBottom" ] ).concat( cProps ); 113 hProps = hProps.concat( [ "marginLeft", "marginRight" ] ); 114 115 // Only animate children with width attributes specified 116 // TODO: is this right? should we include anything with css width specified as well 117 element.find( "*[width]" ).each( function() { 118 var child = $( this ), 119 childOriginal = $.effects.scaledDimensions( child ), 120 childFrom = { 121 height: childOriginal.height * factor.from.y, 122 width: childOriginal.width * factor.from.x, 123 outerHeight: childOriginal.outerHeight * factor.from.y, 124 outerWidth: childOriginal.outerWidth * factor.from.x 125 }, 126 childTo = { 127 height: childOriginal.height * factor.to.y, 128 width: childOriginal.width * factor.to.x, 129 outerHeight: childOriginal.height * factor.to.y, 130 outerWidth: childOriginal.width * factor.to.x 131 }; 132 133 // Vertical props scaling 134 if ( factor.from.y !== factor.to.y ) { 135 childFrom = $.effects.setTransition( child, vProps, factor.from.y, childFrom ); 136 childTo = $.effects.setTransition( child, vProps, factor.to.y, childTo ); 137 } 138 139 // Horizontal props scaling 140 if ( factor.from.x !== factor.to.x ) { 141 childFrom = $.effects.setTransition( child, hProps, factor.from.x, childFrom ); 142 childTo = $.effects.setTransition( child, hProps, factor.to.x, childTo ); 143 } 144 145 if ( restore ) { 146 $.effects.saveStyle( child ); 147 } 148 149 // Animate children 150 child.css( childFrom ); 151 child.animate( childTo, options.duration, options.easing, function() { 152 153 // Restore children 154 if ( restore ) { 155 $.effects.restoreStyle( child ); 156 } 157 } ); 158 } ); 159 } 160 161 // Animate 162 element.animate( to, { 163 queue: false, 164 duration: options.duration, 165 easing: options.easing, 166 complete: function() { 167 168 var offset = element.offset(); 169 170 if ( to.opacity === 0 ) { 171 element.css( "opacity", from.opacity ); 172 } 173 174 if ( !restore ) { 175 element 176 .css( "position", position === "static" ? "relative" : position ) 177 .offset( offset ); 178 179 // Need to save style here so that automatic style restoration 180 // doesn't restore to the original styles from before the animation. 181 $.effects.saveStyle( element ); 182 } 183 184 done(); 185 } 186 } ); 187 188 } ); 189 190 } ) );