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

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


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