1/* 2 * Swipe 1.0 3 * 4 * Brad Birdsall, Prime 5 * Copyright 2011, Licensed GPL & MIT 6 * 7 */ 8 9window.Swipe = function(element, options) { 10 11 // return immediately if element doesn't exist 12 if (!element) return null; 13 14 var _this = this; 15 16 // retreive options 17 this.options = options || {}; 18 this.index = this.options.startSlide || 0; 19 this.speed = this.options.speed || 300; 20 this.callback = this.options.callback || function() {}; 21 this.delay = this.options.auto || 0; 22 23 // reference dom elements 24 this.container = element; 25 this.element = this.container.children[0]; // the slide pane 26 27 // static css 28 this.container.style.overflow = 'hidden'; 29 this.element.style.listStyle = 'none'; 30 31 // trigger slider initialization 32 this.setup(); 33 34 // begin auto slideshow 35 this.begin(); 36 37 // add event listeners 38 if (this.element.addEventListener) { 39 this.element.addEventListener('touchstart', this, false); 40 this.element.addEventListener('touchmove', this, false); 41 this.element.addEventListener('touchend', this, false); 42 this.element.addEventListener('webkitTransitionEnd', this, false); 43 this.element.addEventListener('msTransitionEnd', this, false); 44 this.element.addEventListener('oTransitionEnd', this, false); 45 this.element.addEventListener('transitionend', this, false); 46 window.addEventListener('resize', this, false); 47 } 48 49}; 50 51Swipe.prototype = { 52 53 setup: function() { 54 55 // get and measure amt of slides 56 this.slides = this.element.children; 57 this.length = this.slides.length; 58 59 // return immediately if their are less than two slides 60 if (this.length < 2) return null; 61 62 // determine width of each slide 63 this.width = this.container.getBoundingClientRect().width; 64 65 // return immediately if measurement fails 66 if (!this.width) return null; 67 68 // hide slider element but keep positioning during setup 69 this.container.style.visibility = 'hidden'; 70 71 // dynamic css 72 this.element.style.width = (this.slides.length * this.width) + 'px'; 73 var index = this.slides.length; 74 while (index--) { 75 var el = this.slides[index]; 76 el.style.width = this.width + 'px'; 77 el.style.display = 'table-cell'; 78 el.style.verticalAlign = 'top'; 79 } 80 81 // set start position and force translate to remove initial flickering 82 this.slide(this.index, 0); 83 84 // show slider element 85 this.container.style.visibility = 'visible'; 86 87 }, 88 89 slide: function(index, duration) { 90 91 var style = this.element.style; 92 93 // fallback to default speed 94 if (duration == undefined) { 95 duration = this.speed; 96 } 97 98 // set duration speed (0 represents 1-to-1 scrolling) 99 style.webkitTransitionDuration = style.MozTransitionDuration = style.msTransitionDuration = style.OTransitionDuration = style.transitionDuration = duration + 'ms'; 100 101 // translate to given index position 102 style.MozTransform = style.webkitTransform = 'translate3d(' + -(index * this.width) + 'px,0,0)'; 103 style.msTransform = style.OTransform = 'translateX(' + -(index * this.width) + 'px)'; 104 105 // set new index to allow for expression arguments 106 this.index = index; 107 108 }, 109 110 getPos: function() { 111 112 // return current index position 113 return this.index; 114 115 }, 116 117 prev: function(delay) { 118 119 // cancel next scheduled automatic transition, if any 120 this.delay = delay || 0; 121 clearTimeout(this.interval); 122 123 // if not at first slide 124 if (this.index) this.slide(this.index-1, this.speed); 125 126 }, 127 128 next: function(delay) { 129 130 // cancel next scheduled automatic transition, if any 131 this.delay = delay || 0; 132 clearTimeout(this.interval); 133 134 if (this.index < this.length - 1) this.slide(this.index+1, this.speed); // if not last slide 135 else this.slide(0, this.speed); //if last slide return to start 136 137 }, 138 139 begin: function() { 140 141 var _this = this; 142 143 this.interval = (this.delay) 144 ? setTimeout(function() { 145 _this.next(_this.delay); 146 }, this.delay) 147 : 0; 148 149 }, 150 151 stop: function() { 152 this.delay = 0; 153 clearTimeout(this.interval); 154 }, 155 156 resume: function() { 157 this.delay = this.options.auto || 0; 158 this.begin(); 159 }, 160 161 handleEvent: function(e) { 162 switch (e.type) { 163 case 'touchstart': this.onTouchStart(e); break; 164 case 'touchmove': this.onTouchMove(e); break; 165 case 'touchend': this.onTouchEnd(e); break; 166 case 'webkitTransitionEnd': 167 case 'msTransitionEnd': 168 case 'oTransitionEnd': 169 case 'transitionend': this.transitionEnd(e); break; 170 case 'resize': this.setup(); break; 171 } 172 }, 173 174 transitionEnd: function(e) { 175 176 if (this.delay) this.begin(); 177 178 this.callback(e, this.index, this.slides[this.index]); 179 180 }, 181 182 onTouchStart: function(e) { 183 184 this.start = { 185 186 // get touch coordinates for delta calculations in onTouchMove 187 pageX: e.touches[0].pageX, 188 pageY: e.touches[0].pageY, 189 190 // set initial timestamp of touch sequence 191 time: Number( new Date() ) 192 193 }; 194 195 // used for testing first onTouchMove event 196 this.isScrolling = undefined; 197 198 // reset deltaX 199 this.deltaX = 0; 200 201 // set transition time to 0 for 1-to-1 touch movement 202 this.element.style.MozTransitionDuration = this.element.style.webkitTransitionDuration = 0; 203 204 }, 205 206 onTouchMove: function(e) { 207 208 // ensure swiping with one touch and not pinching 209 if(e.touches.length > 1 || e.scale && e.scale !== 1) return; 210 211 this.deltaX = e.touches[0].pageX - this.start.pageX; 212 213 // determine if scrolling test has run - one time test 214 if ( typeof this.isScrolling == 'undefined') { 215 this.isScrolling = !!( this.isScrolling || Math.abs(this.deltaX) < Math.abs(e.touches[0].pageY - this.start.pageY) ); 216 } 217 218 // if user is not trying to scroll vertically 219 if (!this.isScrolling) { 220 221 // prevent native scrolling 222 e.preventDefault(); 223 224 // cancel slideshow 225 clearTimeout(this.interval); 226 227 // increase resistance if first or last slide 228 this.deltaX = 229 this.deltaX / 230 ( (!this.index && this.deltaX > 0 // if first slide and sliding left 231 || this.index == this.length - 1 // or if last slide and sliding right 232 && this.deltaX < 0 // and if sliding at all 233 ) ? 234 ( Math.abs(this.deltaX) / this.width + 1 ) // determine resistance level 235 : 1 ); // no resistance if false 236 237 // translate immediately 1-to-1 238 this.element.style.MozTransform = this.element.style.webkitTransform = 'translate3d(' + (this.deltaX - this.index * this.width) + 'px,0,0)'; 239 240 } 241 242 }, 243 244 onTouchEnd: function(e) { 245 246 // determine if slide attempt triggers next/prev slide 247 var isValidSlide = 248 Number(new Date()) - this.start.time < 250 // if slide duration is less than 250ms 249 && Math.abs(this.deltaX) > 20 // and if slide amt is greater than 20px 250 || Math.abs(this.deltaX) > this.width/2, // or if slide amt is greater than half the width 251 252 // determine if slide attempt is past start and end 253 isPastBounds = 254 !this.index && this.deltaX > 0 // if first slide and slide amt is greater than 0 255 || this.index == this.length - 1 && this.deltaX < 0; // or if last slide and slide amt is less than 0 256 257 // if not scrolling vertically 258 if (!this.isScrolling) { 259 260 // call slide function with slide end value based on isValidSlide and isPastBounds tests 261 this.slide( this.index + ( isValidSlide && !isPastBounds ? (this.deltaX < 0 ? 1 : -1) : 0 ), this.speed ); 262 263 } 264 265 } 266 267};
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.