├── README.md ├── example.css ├── index.html └── jquery.yatouchslider.js /README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yandex-ui/yaTouchSlider/d526d09b6e451b5822495ce2b33a6517b7b94c61/README.md -------------------------------------------------------------------------------- /example.css: -------------------------------------------------------------------------------- 1 | .b-page { 2 | margin: 0; 3 | -webkit-text-size-adjust: none; 4 | } 5 | .b-wrapper { 6 | overflow: hidden; 7 | } 8 | .b-menu { 9 | float: left; 10 | display: -webkit-box; 11 | margin: 0; 12 | padding: 0; 13 | list-style: none; 14 | } 15 | .b-menu__item { 16 | font-size: 96px; 17 | color: #ccc; 18 | text-align: center; 19 | width: 120px; 20 | height: 120px; 21 | background: #eee; 22 | border: 2px solid #ccc; 23 | } 24 | .b-menu__item + .b-menu__item { 25 | margin-left: 10px; 26 | } 27 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | touchSlider example 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 26 |
27 | 28 |
29 | 30 | 50 | 51 | -------------------------------------------------------------------------------- /jquery.yatouchslider.js: -------------------------------------------------------------------------------- 1 | /** 2 | * jQuery yaTouchSlider plugin 3 | * 4 | * Copyright (c) 2010-2011 Kir Belevich (deepsweet@yandex-team.ru) 5 | * Dual licensed under the MIT and GPL licenses: 6 | * http://www.opensource.org/licenses/mit-license.php 7 | * http://www.gnu.org/licenses/gpl.html 8 | * 9 | * @version 0.2 10 | */ 11 | 12 | (function($) { 13 | 14 | $.fn.yaTouchSlider = function(options) { 15 | 16 | var defaults = { 17 | step: undefined, // step 18 | threshold: 30, // threshold (pixels) that must be overcome 19 | acceleration: true, // enable/disable slider acceleration boost 20 | preventVert: true, // prevent vertical scroll while sliding 21 | preventVertThreshold: 5 // vertical scroll preventing threshold (pixels) 22 | }, 23 | step; 24 | 25 | options = $.extend(defaults, options); 26 | 27 | step = options.step || window.innerWidth; // step or the whole screen width 28 | 29 | return this.each(function(i, el) { 30 | 31 | var x1, shiftX, 32 | y1, shiftY, 33 | t1, 34 | width = $(el).outerWidth(), // actual width 35 | currentX = (new WebKitCSSMatrix(getComputedStyle(el).webkitTransform)).m41, // initial shift 36 | currentI = ~~(-currentX / step), // initial index 37 | limitX = window.innerWidth - width, // max shift 38 | limitI = Math.ceil(-limitX / step) || 1; // max index 39 | 40 | if (width > window.innerWidth) { 41 | 42 | function slide(shift) { 43 | shiftAbs = Math.abs(shift); 44 | 45 | var timeShift = Date.now() - t1, 46 | speed = shiftAbs / timeShift, // pixels in ms 47 | accel = 1, 48 | animationTime = '0.2'; 49 | 50 | // slider acceleration 51 | if (options.acceleration) { 52 | accel = speed > 0.3 && speed < 0.6 ? 2 : 53 | speed >= 0.6 && speed < 1 ? 3 : 54 | speed >= 1 ? 4 : 55 | 1; 56 | 57 | animationTime = accel >= 3 ? '0.3' : '0.2'; 58 | } 59 | 60 | if (shiftAbs > options.threshold || !t1) { 61 | // more than one step 62 | if (shiftAbs > step) { 63 | currentX += ~~(shift/step)*step; 64 | } 65 | 66 | // left or right direction 67 | if (shift > 0) { 68 | currentX += step * accel; 69 | currentI -= accel; 70 | } else if (shift < 0) { 71 | currentX -= step * accel; 72 | currentI += accel; 73 | } 74 | 75 | // left or right limit 76 | if (currentX > 0) { 77 | currentX = currentI = 0; 78 | } else if (currentX < limitX) { 79 | currentX = limitX; 80 | currentI = limitI; 81 | } 82 | } 83 | 84 | // callback after each slide 85 | if (options.callback) { 86 | $(el).one('webkitTransitionEnd', function() { 87 | options.callback({ 88 | currentX: currentX, 89 | limitX: limitX, 90 | currentI: currentI, 91 | limitI: limitI, 92 | speed: speed.toFixed(2), 93 | timeShift: timeShift, 94 | acceleration: accel, 95 | animationTime: animationTime 96 | }); 97 | }); 98 | } 99 | 100 | // animate to calculated position 101 | $(el).css({ 102 | '-webkit-transition':'-webkit-transform ' + animationTime + 's ease-out', 103 | '-webkit-transform': 'translate3d(' + currentX + 'px, 0, 0)' 104 | }); 105 | 106 | // reset 107 | x1 = y1 = shiftX = shiftY = t1 = undefined; 108 | }; 109 | 110 | 111 | $(el) 112 | .css('-webkit-transform', 'translateZ(0)') 113 | .bind({ 114 | // start 115 | 'touchstart.touchSlides': function(e) { 116 | var eo = e.originalEvent.touches[0]; 117 | x1 = eo.pageX; 118 | y1 = eo.pageY; 119 | $(this).css('-webkit-transition', 'none'); 120 | t1 = Date.now(); 121 | }, 122 | 123 | // move 124 | 'touchmove.touchSlides': function(e) { 125 | var eo = e.originalEvent.touches[0]; 126 | shiftX = eo.pageX - x1; 127 | shiftY = eo.pageY - y1; 128 | 129 | $(el).css('-webkit-transform', 'translate3d(' + (currentX + shiftX ) + 'px, 0, 0)'); 130 | if (options.preventVert && Math.abs(shiftY) > options.preventVertThreshold) { 131 | e.preventDefault(); 132 | } 133 | }, 134 | 135 | // end 136 | 'touchend.touchSlides': function(e) { 137 | slide(shiftX); 138 | }, 139 | 140 | // cancel / reset 141 | 'touchcancel.touchSlides': function() { 142 | x1 = y1 = shiftX = shiftY = t1 = undefined; 143 | }, 144 | 145 | // left custom slide event 146 | 'slideLeft.touchSlides': function(e, customStep) { 147 | slide(customStep || step); 148 | }, 149 | 150 | // right custom slide event 151 | 'slideRight.touchSlides': function(e, customStep) { 152 | slide(-customStep || -step); 153 | } 154 | }); 155 | 156 | // correction of current position after device rotation 157 | $(window).bind('orientationchange', function() { 158 | step = options.step || window.innerWidth; 159 | 160 | if (Math.abs(window.orientation) == 90 && currentX - limitX <= window.innerWidth) { 161 | currentX = limitX = window.innerWidth - width; 162 | currentI++; 163 | slide(0); 164 | } else { 165 | limitX = window.innerWidth - width; 166 | currentI = currentI - Math.ceil((currentX - limitX)/step); 167 | slide(0); 168 | } 169 | }); 170 | 171 | } 172 | }); 173 | 174 | }; 175 | 176 | // untouch 177 | $.fn.yaUntouchSlider = function() { 178 | 179 | return this.each(function(i, el) { 180 | $(el).unbind('.touchSlides'); 181 | }); 182 | 183 | }; 184 | 185 | })(jQuery); 186 | --------------------------------------------------------------------------------