1/** 2 * Flickity fade v1.0.0 3 * Fade between Flickity slides 4 */ 5 6/* jshint browser: true, undef: true, unused: true */ 7 8( function( window, factory ) { 9 // universal module definition 10 /*globals define, module, require */ 11 if ( typeof define == 'function' && define.amd ) { 12 // AMD 13 define( [ 14 'flickity/js/index', 15 'fizzy-ui-utils/utils', 16 ], factory ); 17 } else if ( typeof module == 'object' && module.exports ) { 18 // CommonJS 19 module.exports = factory( 20 require('flickity'), 21 require('fizzy-ui-utils') 22 ); 23 } else { 24 // browser global 25 factory( 26 window.Flickity, 27 window.fizzyUIUtils 28 ); 29 } 30 31 }( this, function factory( Flickity, utils ) { 32 33 // ---- Slide ---- // 34 35 var Slide = Flickity.Slide; 36 37 var slideUpdateTarget = Slide.prototype.updateTarget; 38 Slide.prototype.updateTarget = function() { 39 slideUpdateTarget.apply( this, arguments ); 40 if ( !this.parent.options.fade ) { 41 return; 42 } 43 // position cells at selected target 44 var slideTargetX = this.target - this.x; 45 var firstCellX = this.cells[0].x; 46 this.cells.forEach( function( cell ) { 47 var targetX = cell.x - firstCellX - slideTargetX; 48 cell.renderPosition( targetX ); 49 }); 50 }; 51 52 Slide.prototype.setOpacity = function( alpha ) { 53 this.cells.forEach( function( cell ) { 54 cell.element.style.opacity = alpha; 55 }); 56 }; 57 58 // ---- Flickity ---- // 59 60 var proto = Flickity.prototype; 61 62 Flickity.createMethods.push('_createFade'); 63 64 proto._createFade = function() { 65 this.fadeIndex = this.selectedIndex; 66 this.prevSelectedIndex = this.selectedIndex; 67 this.on( 'select', this.onSelectFade ); 68 this.on( 'dragEnd', this.onDragEndFade ); 69 this.on( 'settle', this.onSettleFade ); 70 this.on( 'activate', this.onActivateFade ); 71 this.on( 'deactivate', this.onDeactivateFade ); 72 }; 73 74 var updateSlides = proto.updateSlides; 75 proto.updateSlides = function() { 76 updateSlides.apply( this, arguments ); 77 if ( !this.options.fade ) { 78 return; 79 } 80 // set initial opacity 81 this.slides.forEach( function( slide, i ) { 82 var alpha = i == this.selectedIndex ? 1 : 0; 83 slide.setOpacity( alpha ); 84 }, this ); 85 }; 86 87 /* ---- events ---- */ 88 89 proto.onSelectFade = function() { 90 // in case of resize, keep fadeIndex within current count 91 this.fadeIndex = Math.min( this.prevSelectedIndex, this.slides.length - 1 ); 92 this.prevSelectedIndex = this.selectedIndex; 93 }; 94 95 proto.onSettleFade = function() { 96 delete this.didDragEnd; 97 if ( !this.options.fade ) { 98 return; 99 } 100 // set full and 0 opacity on selected & faded slides 101 this.selectedSlide.setOpacity( 1 ); 102 var fadedSlide = this.slides[ this.fadeIndex ]; 103 if ( fadedSlide && this.fadeIndex != this.selectedIndex ) { 104 this.slides[ this.fadeIndex ].setOpacity( 0 ); 105 } 106 }; 107 108 proto.onDragEndFade = function() { 109 // set flag 110 this.didDragEnd = true; 111 }; 112 113 proto.onActivateFade = function() { 114 if ( this.options.fade ) { 115 this.element.classList.add('is-fade'); 116 } 117 }; 118 119 proto.onDeactivateFade = function() { 120 if ( !this.options.fade ) { 121 return; 122 } 123 this.element.classList.remove('is-fade'); 124 // reset opacity 125 this.slides.forEach( function( slide ) { 126 slide.setOpacity(''); 127 }); 128 }; 129 130 /* ---- position & fading ---- */ 131 132 var positionSlider = proto.positionSlider; 133 proto.positionSlider = function() { 134 if ( !this.options.fade ) { 135 positionSlider.apply( this, arguments ); 136 return; 137 } 138 139 this.fadeSlides(); 140 this.dispatchScrollEvent(); 141 }; 142 143 var positionSliderAtSelected = proto.positionSliderAtSelected; 144 proto.positionSliderAtSelected = function() { 145 if ( this.options.fade ) { 146 // position fade slider at origin 147 this.setTranslateX( 0 ); 148 } 149 positionSliderAtSelected.apply( this, arguments ); 150 }; 151 152 proto.fadeSlides = function() { 153 if ( this.slides.length < 2 ) { 154 return; 155 } 156 // get slides to fade-in & fade-out 157 var indexes = this.getFadeIndexes(); 158 var fadeSlideA = this.slides[ indexes.a ]; 159 var fadeSlideB = this.slides[ indexes.b ]; 160 var distance = this.wrapDifference( fadeSlideA.target, fadeSlideB.target ); 161 var progress = this.wrapDifference( fadeSlideA.target, -this.x ); 162 progress = progress / distance; 163 164 fadeSlideA.setOpacity( 1 - progress ); 165 fadeSlideB.setOpacity( progress ); 166 167 // hide previous slide 168 var fadeHideIndex = indexes.a; 169 if ( this.isDragging ) { 170 fadeHideIndex = progress > 0.5 ? indexes.a : indexes.b; 171 } 172 var isNewHideIndex = this.fadeHideIndex != undefined && 173 this.fadeHideIndex != fadeHideIndex && 174 this.fadeHideIndex != indexes.a && 175 this.fadeHideIndex != indexes.b; 176 if ( isNewHideIndex ) { 177 // new fadeHideSlide set, hide previous 178 this.slides[ this.fadeHideIndex ].setOpacity( 0 ); 179 } 180 this.fadeHideIndex = fadeHideIndex; 181 }; 182 183 proto.getFadeIndexes = function() { 184 if ( !this.isDragging && !this.didDragEnd ) { 185 return { 186 a: this.fadeIndex, 187 b: this.selectedIndex, 188 }; 189 } 190 if ( this.options.wrapAround ) { 191 return this.getFadeDragWrapIndexes(); 192 } else { 193 return this.getFadeDragLimitIndexes(); 194 } 195 }; 196 197 proto.getFadeDragWrapIndexes = function() { 198 var distances = this.slides.map( function( slide, i ) {
199 return this.getSlideDistance( -this.x, i ); 200 }, this ); 201 var absDistances = distances.map( function( distance ) { 202 return Math.abs( distance ); 203 }); 204 var minDistance = Math.min.apply( Math, absDistances ); 205 var closestIndex = absDistances.indexOf( minDistance ); 206 var distance = distances[ closestIndex ]; 207 var len = this.slides.length; 208 209 var delta = distance >= 0 ? 1 : -1; 210 return { 211 a: closestIndex, 212 b: utils.modulo( closestIndex + delta, len ), 213 }; 214 }; 215 216 proto.getFadeDragLimitIndexes = function() { 217 // calculate closest previous slide 218 var dragIndex = 0; 219 for ( var i=0; i < this.slides.length - 1; i++ ) { 220 var slide = this.slides[i]; 221 if ( -this.x < slide.target ) { 222 break; 223 } 224 dragIndex = i; 225 } 226 return { 227 a: dragIndex, 228 b: dragIndex + 1, 229 }; 230 }; 231 232 proto.wrapDifference = function( a, b ) { 233 var diff = b - a; 234 235 if ( !this.options.wrapAround ) { 236 return diff; 237 } 238 239 var diffPlus = diff + this.slideableWidth; 240 var diffMinus = diff - this.slideableWidth; 241 if ( Math.abs( diffPlus ) < Math.abs( diff ) ) { 242 diff = diffPlus; 243 } 244 if ( Math.abs( diffMinus ) < Math.abs( diff ) ) { 245 diff = diffMinus; 246 } 247 return diff; 248 }; 249 250 // ---- wrapAround ---- // 251 252 var _getWrapShiftCells = proto._getWrapShiftCells; 253 proto._getWrapShiftCells = function() { 254 if ( !this.options.fade ) { 255 _getWrapShiftCells.apply( this, arguments ); 256 } 257 }; 258 259 var shiftWrapCells = proto.shiftWrapCells; 260 proto.shiftWrapCells = function() { 261 if ( !this.options.fade ) { 262 shiftWrapCells.apply( this, arguments ); 263 } 264 }; 265 266 return Flickity; 267 268 }));
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.