Javascript-форум (https://javascript.ru/forum/)
-   jQuery (https://javascript.ru/forum/jquery/)
-   -   Как сделать сопротивление при touch управление слайдером (https://javascript.ru/forum/jquery/65240-kak-sdelat-soprotivlenie-pri-touch-upravlenie-slajjderom.html)

Роман Андреевич 06.10.2016 17:46

Как сделать сопротивление при touch управление слайдером
 
Всем доброго времени суток.

Суть вопроса в следующем. Есть слайдер, который состоит из списка ul в котором любое количество li, в которых есть какой то контент.

Управляется touch и mouse событиями. Как сделать, если перед (назад листаем) или после (вперед листаем) нет предыдущего или следующего слайда, сопротивление (если я правильно это называю).

Если кто нибудь делал уже такие вещи помогите советом. Или где почитать подробнее можно об этом
Заранее благодарю.

Coriolan161 06.10.2016 18:12

Роман Андреевич,
Роман Андреевич, либо делать цикл из слайдов, либо return в touch и mousemove обработчиках

Coriolan161 06.10.2016 18:14

Роман Андреевич,
можно залезть в карусельные плагины и подсмотреть

рони 06.10.2016 18:21

Роман Андреевич,
может код, а лучше макет

Роман Андреевич 06.10.2016 18:21

Coriolan161,
changeStyle($this, "margin-left", distance);

					if (directionSide == "left") {

						if (!nextItem.length) {

							//different = 

							distance = distance + (distance / 10);

							changeStyle($this, "margin-left", distance);

						}

					} else if (directionSide == "right") {


						if (!prevItem.length) {

							distance = distance / 10;

							changeStyle($this, "margin-left", distance);

						}

					}


Слайды поставлены float:left а ширина списка ul равна ширине слайда * их кол-во.

Слайдер двигается с помощью координат при touchstart или mousedown а потом соответственно move.

Двигаем свойство margin-left. distance это как раз и есть смещение. Если стоит слайдер первый, то перед ним ничего нет, соответственно distance делим на какое нибудь число и получается нужный эффект, тут исчисления идут от 0. А вот если слайдер последний, то distance нельзя делить на 10, потому что получается, слайдер смещается в ненужную сторону.

если не сложно, поясните как сделать через цикл и для чего return в move событиях????

Роман Андреевич 06.10.2016 18:23

<section class="slider">
		<h2>slider</h2>
		<nav class="slider_block">
			<ul class="slider_list">
				<li class="slider_item first active">
					<div class="div_block"></div>
				</li>
				<li class="slider_item second">
					<div class="div_block"></div>
				</li>
				<li class="slider_item third">
					<div class="div_block"></div>
				</li>
				<li class="slider_item fourth">
					<div class="div_block"></div>
				</li>
				<li class="slider_item fifth">
					<div class="div_block"></div>
				</li>
			</ul>
			<ul class="control">
				<li class="button right"></li>
				<li class="button left"></li>
			</ul>
		</nav>
	</section>

* {padding: 0;margin: 0;list-style-type: none;text-decoration: none;outline: none;-webkit-box-sizing: border-box;-moz-box-sizing: border-box;-ms-box-sizing: border-box;-o-box-sizing: border-box;box-sizing: border-box;}

		section.slider {width: 100%;padding: 5% 0;}
		nav.slider_block {width: 100%;position: relative;overflow: hidden;}
		ul.slider_list {width: 100%;}
		ul.slider_list:after {content: "";display: block;width: 0;height: 0;clear: both;}

		ul.slider_list li.slider_item {float: left;}
		ul.slider_list li.slider_item.first {background-color: #e43c1e;}
		ul.slider_list li.slider_item.second {background-color: #f0b21b;}
		ul.slider_list li.slider_item.third {background-color: green;}
		ul.slider_list li.slider_item.fourth {background-color: black;}
		ul.slider_list li.slider_item.fifth {background-color: blue;}
		
		div.div_block {width: 100%;height: 300px;}

		ul.control.hiden {display: none;}		
		ul.control li.button {width: 50px;height: 50px;background-color: #ccc;position: absolute;top: 50%;transform: translateY(-50%);}
		ul.control li.button.right {right: 0;}
		ul.control li.button.left {left: 0;}

$(document).ready(function() {

			var   animationFlag = 0,
				slider = $(".slider_list"), // блок который сдвигаем
				control = $(".control"), // кнопки управления слайдером
				needOffset = 0, // порог смещения слайда для перелиставния к следующему слайду
				gor = 0, // первоначальная координата X косания или нажатия мышиной кнопки
				gortwo = 0, // копируем перовначальную координату 
				tor = 0, // переменная для определения направления движения курсора или пальца
				flag = 0, // метка начала череды событий
				direction = 0,
				distance = 0,
				newdistance = 0, 
				directionSide = 0, // направление движения слайдера
				standartDuration = 200,
				sliderDuration, // время движения слайдера 
				eventCounter = 0, //время между событиями в милисекундах
				startEventCounter = 0, // время начала 
				endEventCounter = 0, // время конца 
				firstMargin = 0,
				moveMargin = 0,
				different = 0;

			sliderSize();

			slider.on("touchstart mousedown", function(e){
				e.preventDefault();

				var $this = $(this);

				startEventCounter = Date.now();
				flag = 1;

			    if (e.type == "touchstart") {

			    	var pos = $this.offset();

						gor = e.changedTouches[0].pageX - pos.left;

			    } else if (e.type == "mousedown") {

					var pos = $this.offset();

						gor = e.pageX - pos.left;

				    $this.css("cursor", "move");

			    }
				
				gortwo = gor;

			});	

			slider.on("touchmove mousemove", function(e) {
				e.preventDefault();

				var $this = $(this),
					sliderBlock = $this.closest(".slider_block"),
					list = sliderBlock.find(".slider_list"),
					item = list.find(".slider_item"),
					itemWidth= item.width(),
					itemLength = item.length,
					activeItem = item.filter(".active"),
					nextItem = activeItem.next(),
					prevItem = activeItem.prev(),
					lastMargin = 0;


				if (flag === 1) {

					if (e.type == "touchmove") {

						direction = e.changedTouches[0].pageX;
						distance = direction - gortwo;
						tor = gor - e.changedTouches[0].pageX;
						gor = e.changedTouches[0].pageX;

					} else if (e.type == "mousemove") {

						direction = e.pageX;
						distance = direction - gortwo;
						tor = gor - e.pageX;
						gor = e.pageX;

					}

					direction_Side();
					changeStyle($this, "margin-left", distance);

					if (directionSide == "left") {

						if (!nextItem.length) {

							//different = 

							distance = distance + (distance / 10);

							changeStyle($this, "margin-left", distance);

						}

					} else if (directionSide == "right") {


						if (!prevItem.length) {

							distance = distance / 10;

							changeStyle($this, "margin-left", distance);

						}

					}

				}

			});

			slider.on("touchend mouseup", function(e) {
		    	e.preventDefault();

		    	endEventCounter = Date.now();

				var $this = $(this),
					controlButton = $this.siblings(".control"),
					sliderBlock = $this.closest(".slider_block"),
					sliderOffset = sliderBlock.offset().left,
					sliderList = sliderBlock.find(".slider_list"),
					item = sliderList.find(".slider_item"),
					itemIndex = item.index(),
					activeItem = item.filter(".active"),
					nextItem = activeItem.next(),
					prevItem = activeItem.prev(),
					itemLength = item.length,
					ass = 0;

				if (e.type == "touchend") {



				} else if (e.type == "mouseup") {

					$(this).css("cursor", "default");
					
				}

				if (directionSide == "left") {

					if (nextItem.length) {

						newdistance = (distance * - 1) - (item.width() * activeItem.index());

						letsRide(sliderList, nextItem, sliderOffset);	

					} else {

						letsRide(sliderList, activeItem, sliderOffset);

					}

				} else if (directionSide == "right") {

					if (prevItem.length) {

						newdistance = ((distance * - 1) - (item.width() * activeItem.index())) * - 1;

						letsRide(sliderList, prevItem, sliderOffset);

					} else {

						letsRide(sliderList, activeItem, sliderOffset);

					}

				}

				if (eventCounter > 300 && newdistance < needOffset) {

					letsRide(sliderList, activeItem, sliderOffset);

				}

				flag = 0;
				distance = 0;
				tor = 0;
				directionSide = "undefined";

			});

			function showElements() {for (var i = 0; i < arguments.length; i++) {arguments[i].show(100);}}
			function hideElements() {for (var i = 0; i < arguments.length; i++) {arguments[i].hide(100);}}

			function letsRide(moveelement, slide, distance) {

				eventCounter = endEventCounter - startEventCounter;

				if (eventCounter < 200) {

					sliderDuration = eventCounter;

				} else {

					sliderDuration = 200;

				}

				slidePosition = slide.offset().left - distance;
				slide.addClass("active").siblings().removeClass("active");
				moveelement.stop().animate({"margin-left": "-=" + slidePosition}, sliderDuration);

			}

			function direction_Side() {

				if (tor > 0) {

					directionSide = "left";	

				} else if (tor < 0) {

					directionSide = "right";		

				}

			}

			function sliderSize() {

				var container = $(".slider_block");
										
				container.each(function() {

					var $this = $(this),
						win = $this.closest(".slider"),
						winWidth = win.width(),
						list = $this.find(".slider_list"),
						item = list.find("li"),
						itemLength = item.length,
						itemWidth = item.width(winWidth),
						listWidth = list.width(winWidth * itemLength),
						activeItem = item.filter(".active"),
						activeItemIndex = activeItem.index(),
						position = winWidth * activeItemIndex;

					changeStyle(list, "margin-left" , - position);

					needOffset = winWidth/3;

				});	

			}
			
			function changeStyle(element, property, value) {
				
				element.css(property, value);

			}

			function newClass(element, className) {element.addClass(className);}
			function deleteClass(element, className) {element.removeClass(className);}

			$(window).on("orientationchange resize", sliderSize);

		});

Роман Андреевич 06.10.2016 18:24

Я думаю что галактику я не открыл, но просто понять хочу как сделать сопротивление при последнем слайде.
Все работает, код конечно не идеален но для новичка должен пойти)))

Заранее благодрю

рони 06.10.2016 18:26

Роман Андреевич,
может плагин взять и не мучатся
http://owlgraphic.com/owlcarousel/

Роман Андреевич 06.10.2016 18:26

Coriolan161,
В карусельные плагины залазил, особо не помогло, это нужно слишком много времени, что бы разобрать хороший код. А зачастую такой функционал не каждый слайдер поддерживает.

Роман Андреевич 06.10.2016 18:28

рони,
Да, может, но хочу понимать суть. Использовать чужие плагины проще, но не факт что лучше. ПОэтому прошу помощи у тех, кто решал такие задачи

Роман Андреевич 06.10.2016 18:31

В сети особо нет ответов на такие задачи. Поиск выдает готовые варианты.

Coriolan161 06.10.2016 18:31

Роман Андреевич,
Можно достать номер слайда в коллекции и чуть попробовать поменять

if (directionSide == "left" && index !== 1) {
  if (!nextItem.length) {
    //different = 
    distance = distance + (distance / 10);
    changeStyle($this, "margin-left", distance);
  }
} else if (directionSide == "right" && index !== 'длина коллекции'-1 ) {


Немного непонятно кто такие nextItem.length и prevItem.length
Это в айтемах коллекции лежат ещё какие-то айтемы?

Роман Андреевич 06.10.2016 18:32

Coriolan161,
Это следующий и предыдущий слайд от активного (который сейчас показывается), т.к. слайд равен ширине экрана.

Coriolan161 06.10.2016 18:33

Роман Андреевич,
Зацикливание тоже делается через проверку номера текущего слайда, если последний вернуться к (".slider_item")[0]

Coriolan161 06.10.2016 18:35

Роман Андреевич,
карусели для этого клонируют айтемы

Роман Андреевич 06.10.2016 18:41

Coriolan161,
В этом и суть при управлении на кнопках, происходит зацикливание, тут все просто и работает.

А вот когда листаешь пальцем и упираешься в последний слайд при этом пытаешься листать дальше, получаешь сопротивление. Т.е. сам слайдер плавно отодвигается на небольшое расстояние от края, а не следует за пальцем.

Роман Андреевич 06.10.2016 18:42

По сути не важен номер слайда в коллекции, потому что мы знаем что есть (или нету) следующий или предыдущий слайд.

рони 06.10.2016 19:06

Роман Андреевич,
строка 92
if (!nextItem.length && activeItem.index() < itemLength - 2) {

рони 06.10.2016 19:17

Роман Андреевич,
http://javascript.ru/forum/dom-windo...tml#post318030

рони 07.10.2016 00:45

Роман Андреевич,
http://www.jqueryscript.net/demo/Res.../swiper-demos/

Aetae 07.10.2016 03:25

Цитата:

Сообщение от Роман Андреевич (Сообщение 430899)
В сети особо нет ответов на такие задачи. Поиск выдает готовые варианты.

Потому что это скучно. Анимация в зависимости от элементарных условий. На чистом js она простая но нудная. Потому все используют либо готовые решения, либо пишут ещё один велосипед, который сразу целиком дарят общественности. Статью тут писать не о чем.


Часовой пояс GMT +3, время: 09:07.