дыдыкин егор

1,763 views
1,660 views

Published on

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
1,763
On SlideShare
0
From Embeds
0
Number of Embeds
1,148
Actions
Shares
0
Downloads
13
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide
  • Свайп, в простонародье – листалка. Позволяет листать из стороны в сторону «страницы» посредствам привычного движения пальцем.(ДЕМО)
  • Специально для работы с тач устройствами ввода в браузерах реализованы событияНо не все браузеры на тач устройствах их поддерживают
  • Эмуляция через мышиныеОблом - WP
  • Стандартная последовательность
  • Облом – WPПотому swipe реализован только на тач событиях. (ДЕМО)
  • В тач событие падает информация о касаниях:touches - все касания, ассоциированные с событиемchangedTouches - касания, по которым есть измененияtargetTouches - касания, ассоциированные с target события
  • Каждому касанию присваивается уникальный идентификатор. В разных браузерах может иметь различные значения, в одних постоянно инкрементируется, в других сбрасывается, когда прикосновений больше нет.Так же объект касания содержит информацию о координатах - относительно вьюпорта (client), экрана (screen) и страницы (page).
  • проверяем флаг started (не был ли уже начат свайп) и кол-во touches. Если свайп уже идет или toches не один, значит пользователь орудует несколькими пальцами и реагировать на это не надо, а значит return
  • Запоминаем текущее касание и координатыставим флаг detecting = true, что далее на touchmove надо определить, хотел ли пользователь сделать свайп или он просто прокручивает страницу или тапнул по ссылке
  • первым делом проверяем, если не стоит ни started, ни detecting, не делаем ничего. Не наш случай
  • определяем смещение пальца относительно сохраненного касания. Если смещение больше по оси х, чем по у, значит пользователь листает
  • отменяем поведение по умолчанию, started = trueВ любом случае detecting = false (ДЕМО)
  • В любом случае detecting = false
  • отменяем поведение по умолчанию
  • восстанавливаем интересующее нас касание по идентификатору из changedTouches.Если восстановить не удалось - return
  • Вычисляем смещение пальца по оси х
  • Если свайпить некуда, делим смещение на некоторый “коэффициент сопротивления”, делая тем самым вид, что блок как бы сопротивляется движению, чтобы дать пользователю понять, что листать некуда
  • отрисовываем смещение блока
  • восстанавливаем интересующее нас касание по идентификатору из changedTouches. Если восстановить не удалось - return
  • Отменяем действие по-умолчанию (ДЕМО)если этого не сделать, и в блоке к которому мы пролистываем по текущим координатам окажется ссылка, по ней произойдет кли
  • устанавливаем направление свайпа
  • Анимируем пролистываниепролистываем блок в нужную сторону
  • Для того, чтобы сделать листалку, нужно расположить страницы в рядСтраницы же были разбиты на 3 логичные группы:страницы слевацентральная страницы - всегда однаи страницы справа
  • Каждая из страниц должна быть шириной не больше не меньше родителя.
  • центральная всегда видна, левые смещены на 100% влево, а правые - на 100% вправо.
  • Чтобы получить ширину страницы 100% родителя, нужно каким-то образом задать ширину всей таблицы в <колво страниц>*100%, и самим страницам в 100%/<колво страниц>, что без дополнительных JS манипуляций не возможно и грозит погрешностями и неровностями, а так же дополнительными расчетами.
  • Обертке блока указали высоту, position:relative и overflow:hidden, снизив нагрузку на браузер
  • нужно максимально обособить страницы друг от друга – каждой страницы указаны position:absolute; и соответствующие координаты и размеры.
  • Анимируются страницы средствами CSS - transition. (ДЕМО)Если анимировать left, получается очень медленно. Гораздо быстрее работает translate, а еще быстрее translate3d из css-трансформаций.
  • страницам указан left:0 и оба варианта translateсо значениями смещения по горизонтали -100%, 0 и 100%
  • Стопки слева и справа
  • Следующие правая и левая
  • Изначально анимации выключен, по событию touchmove для страницы устанавливается translate, со значением смещения по горизонтали равным смещению пальца
  • Одновременно двигаются три страницы - текущая видимая и по странице слева и справа. для правой и левой страниц смещение равноширине страницы с соответствующим положению знаком (для правой плюс, для левой минус) плюс смещение пальца.
  • По событию touchend или touchcancel страницам устанавливается класс swipe__page_animating, включающий css-анимации, И финальные смещенияЛибо возвращаем все назад, либо пролистываем
  • На событииtransitionEndотключаются анимацииЗаново выбираются next страницыУстанавливаются новые классы принадлежности к группам
  • Удаляются установленныеинлайновые стилиИ очищаются установленные флаги вроде startedВозврат к исходному состоянию(ДЕМО)
  • Например, в случае блока новостей, на примере которого я рассказываю о свайпе, мы сделали привычные всем табы. Пользователь может тапнуть по закладке и перелистнуть страницу.
  • дыдыкин егор

    1. 1. Современный web-application
    2. 2. 2
    3. 3. 3
    4. 4. SWIPE / Листалка
    5. 5. Touch events touchstart touchmove touchend touchcancel
    6. 6. Touch/mouse events touchstart – mousedown touchmove – mousemove touchend – mouseup touchcancel – mouseup
    7. 7. Mouse events mousedown mousemove mouseup click
    8. 8. EPIC FAIL mousedown mousemove mouseup click mousemove mousedown mouseup click
    9. 9. Touch Event touches changedTouches targetTouches
    10. 10. Touch Object identifier pageX/Y screenX/Y clientX/Y
    11. 11. touchstart if (e.touches.length != 1 || started){ return; }
    12. 12. touchstart if (e.touches.length != 1 || started){ return; } detecting = true; touch = e.changedTouches[0]; x = pageX; y = pageY;
    13. 13. touchmove if (!started && !detecting){ return; } if (detecting){ detect(); } if (started){ draw(); }
    14. 14. Touchmove - detecting if (e.changedTouches.indexOf(touch) == -1){ return; }
    15. 15. Touchmove - detecting if (e.changedTouches.indexOf(touch) == -1){ return; } if (abs(x - newX) >= abs(y - newY)){ }
    16. 16. Touchmove - detecting if (e.changedTouches.indexOf(touch) == -1){ return; } if (abs(x - newX) >= abs(y - newY)){ e.preventDefault(); started = true; }
    17. 17. Touchmove - detecting if (e.changedTouches.indexOf(touch) == -1){ return; } if (abs(x - newX) >= abs(y - newY)){ e.preventDefault(); started = true; } detecting = false;
    18. 18. Touchmove - move e.preventDefault();
    19. 19. Touchmove - move e.preventDefault(); if (e.changedTouches.indexOf(touch) == -1){ return; }
    20. 20. Touchmove - move e.preventDefault(); if (e.changedTouches.indexOf(touch) == -1){ return; } delta = x – newX;
    21. 21. Touchmove - move e.preventDefault(); if (e.changedTouches.indexOf(touch) == -1){ return; } delta = x – newX; if (delta > 0 && !leftPage || delta < 0 && !rightPage){ delta = delta / 5; }
    22. 22. Touchmove - move e.preventDefault(); if (e.changedTouches.indexOf(touch) == -1){ return; } delta = x – newX; if (delta > 0 && !leftPage || delta < 0 && !rightPage){ delta = delta / 5; } moveTo(delta);
    23. 23. Touchend/cancel if (e.changedTouches.indexOf(touch) == -1 || !started){ return; }
    24. 24. Touchend/cancel if (e.changedTouches.indexOf(touch) == -1 || !started){ return; } e.preventDefault();
    25. 25. Touchend/cancel if (e.changedTouches.indexOf(touch) == -1 || !started){ return; } e.preventDefault(); swipeTo = delta < 0 ? left : right;
    26. 26. Touchend/cancel if (e.changedTouches.indexOf(touch) == -1 || !started){ return; } e.preventDefault(); swipeTo = delta < 0 ? left : right; swipe(swipeTo);
    27. 27. «Страницы»
    28. 28. «Страницы» swipeWidth swipeWidth swipeWidth swipeWidth
    29. 29. «Страницы» -100% +100%
    30. 30. «Страницы» - таблица leftPages.length*100% Pages.length*100% 100%/Pages.length 100%/Pages.length 100%/Pages.length
    31. 31. Обертка .swipe { position: relative; overflow: hidden; height: 300px; }
    32. 32. Left/top.swipe__page { overflow: hidden; position: absolute; left: 0; top: 0; width: 100%; height: 100%;}
    33. 33. CSS .swipe__page_animating { transition: transform 200ms linear; }
    34. 34. Translate .swipe__page_left { transform: translate(-100%, 0); transform: translate3d(-100%, 0, 0); } .swipe__page_center { transform: translate(0, 0); transform: translate3d(0, 0, 0); } .swipe__page_right { transform: translate(100%, 0); transform: translate3d(100%, 0, 0); }
    35. 35. «Страницы»
    36. 36. «Страницы» Next left Current Next right
    37. 37. Translate - move transform = translate(delta, 0); delta
    38. 38. Translate - move- swipeWidth + delta swipeWidth + delta
    39. 39. Touchend - swipe
    40. 40. TransitionEnd - clear
    41. 41. TransitionEnd - clear
    42. 42. Совместимость
    43. 43. Tap-events 43
    44. 44. Скорость touchstart ... touchend … ~300ms … click ~250ms ~150ms ~70ms ~7ms 44
    45. 45. Точность 45
    46. 46. Внимание 46
    47. 47. TouchStartif( target.tagName == A || closest(target, A)){ // Сохраняем событие}else{ ignoreEvent = true;} 47
    48. 48. TouchEnd if( !ignoreEvent ){ if( abs(startX - newX) < 4 && abs(startY - newY) < 4 ){ // Создаем событие Click Click._fake = true; dispatchEvent(Click); } } 48
    49. 49. Clickif( !ignoreEvent ){ if( allowClick(event) ){ startTap = true; }else{ event.preventDefault(); event.stopPropagation(); }} 49
    50. 50. AllowClickif( !event ) return true;if( !event._fake ){ fired = e...vent.target != startTarget ||rget) return !( fired || startTap );}else{ return true;} 50
    51. 51. AllowClickif( !event ) return true;if( !event._fake ){ fired = event.target != startTarget; return !( fired || startTap );}else{ return true;} 51
    52. 52. ScrollВертикальный:• iOS - JavaScript• Остальные - Нативный скроллГоризонтальный:• iOS - Zoom*• WebKit - JavaScript• Остальные - Нативный скролл 52
    53. 53. PullToRefresh 53
    54. 54. PullToRefreshScroll scroll:move scroll:end 54
    55. 55. PullToRefresh scroll:move top > 35 startTime = 0; startTime = new Date(); pulltorefresh:push pulltorefresh:pull
    56. 56. PullToRefresh scroll:end pulltorefresh:release new Date() - startTime > 100 pulltorefresh:push pulltorefresh:process
    57. 57. Zoom
    58. 58. Zoom
    59. 59. Zoom
    60. 60. Zoomtransform-origin 50% 50% 0px 0px
    61. 61. Zoom l= x +y 2 2 2 InitialTouchesLength = Math.sqrt( Math.pow( touches[0].x - touches[1].x, 2 ) + Math.pow( touches[0].y - touches[1].y, 2 ) );
    62. 62. Zoom X = X0 – ( X0 – X1 ) / 2; Y = Y0 – ( Y0 – Y1 ) / 2;
    63. 63. Zoom documentX = ( targetX - scrollX - deltaX ) / initialZoom; documentY = ( targetY - scrollY - deltaY ) / initialZoom;
    64. 64. Zoom:touchmovedeltaZoom = currentTouchesLength / initialTouchesLength;currentZoom = initialZoom * deltaZoom;
    65. 65. Zoom:touchmovedeltaZoom = currentTouchesLength / initialTouchesLength;currentZoom = initialZoom * deltaZoom;left = currentTouch.x – ( documentX * currentZoom + deltaX );top = currentTouch.y – ( documentY * currentZoom + deltaY );
    66. 66. Zoom content.style[WebkitTransform] translate3d(+left+px, 0px, 0px) scale3d(+currentZoom+, ’ +currentZoom+, 1)
    67. 67. СПАСИБО! Иван Чашкин, Егор Дыдыкин Front-end разработчикиi.chashkin@corp.mail.ru e.dydykin@corp.mail.ru

    ×