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 35var Slide = Flickity.Slide; 36 37var slideUpdateTarget = Slide.prototype.updateTarget; 38Slide.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 52Slide.prototype.setOpacity = function( alpha ) { 53 this.cells.forEach( function( cell ) { 54 cell.element.style.opacity = alpha; 55 }); 56}; 57 58// ---- Flickity ---- // 59 60var proto = Flickity.prototype; 61 62Flickity.createMethods.push('_createFade'); 63 64proto._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 74var updateSlides = proto.updateSlides; 75proto.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 89proto.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 95proto.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 108proto.onDragEndFade = function() { 109 // set flag 110 this.didDragEnd = true; 111}; 112 113proto.onActivateFade = function() { 114 if ( this.options.fade ) { 115 this.element.classList.add('is-fade'); 116 } 117}; 118 119proto.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 132var positionSlider = proto.positionSlider; 133proto.positionSlider = function() { 134 if ( !this.options.fade ) { 135 positionSlider.apply( this, arguments ); 136 return; 137 } 138 139 this.fadeSlides(); 140 this.dispatchScrollEvent(); 141}; 142 143var positionSliderAtSelected = proto.positionSliderAtSelected; 144proto.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 152proto.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 183proto.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 197proto.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 216proto.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 232proto.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 252var _getWrapShiftCells = proto._getWrapShiftCells; 253proto._getWrapShiftCells = function() { 254 if ( !this.options.fade ) { 255 _getWrapShiftCells.apply( this, arguments ); 256 } 257}; 258 259var shiftWrapCells = proto.shiftWrapCells; 260proto.shiftWrapCells = function() { 261 if ( !this.options.fade ) { 262 shiftWrapCells.apply( this, arguments ); 263 } 264}; 265 266return 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.