SlideShare a Scribd company logo
1 of 67
Современный web-application
2
3
SWIPE / Листалка
Touch events



                 touchstart
                touchmove
                 touchend
               touchcancel
Touch/mouse events



           touchstart – mousedown
          touchmove – mousemove
            touchend – mouseup
         touchcancel – mouseup
Mouse events


 mousedown     mousemove   mouseup   click
EPIC FAIL


  mousedown   mousemove   mouseup   click




 mousemove    mousedown   mouseup   click
Touch Event




                  touches
              changedTouches
               targetTouches
Touch Object


                identifier
                pageX/Y
               screenX/Y
                clientX/Y
touchstart


  if (e.touches.length != 1 || started){
           return;
  }
touchstart


  if (e.touches.length != 1 || started){
           return;
  }

  detecting = true;
  touch = e.changedTouches[0];
  x = pageX;
  y = pageY;
touchmove
            if (!started && !detecting){
                    return;
            }
            if (detecting){
                    detect();
            }

            if (started){
                    draw();
            }
Touchmove - detecting

  if (e.changedTouches.indexOf(touch) == -1){
          return;
  }
Touchmove - detecting

  if (e.changedTouches.indexOf(touch) == -1){
          return;
  }

  if (abs(x - newX) >= abs(y - newY)){


  }
Touchmove - detecting

  if (e.changedTouches.indexOf(touch) == -1){
          return;
  }

  if (abs(x - newX) >= abs(y - newY)){
          e.preventDefault();
          started = true;
  }
Touchmove - detecting

  if (e.changedTouches.indexOf(touch) == -1){
          return;
  }

  if (abs(x - newX) >= abs(y - newY)){
          e.preventDefault();
          started = true;
  }

  detecting = false;
Touchmove - move
  e.preventDefault();
Touchmove - move
  e.preventDefault();
  if (e.changedTouches.indexOf(touch) == -1){
          return;
  }
Touchmove - move
  e.preventDefault();
  if (e.changedTouches.indexOf(touch) == -1){
          return;
  }

  delta = x – newX;
Touchmove - move
  e.preventDefault();
  if (e.changedTouches.indexOf(touch) == -1){
          return;
  }

  delta = x – newX;

  if (delta > 0 && !leftPage || delta < 0 && !rightPage){
           delta = delta / 5;
  }
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);
Touchend/cancel
  if (e.changedTouches.indexOf(touch) == -1 || !started){
          return;
  }
Touchend/cancel
  if (e.changedTouches.indexOf(touch) == -1 || !started){
          return;
  }
  e.preventDefault();
Touchend/cancel
  if (e.changedTouches.indexOf(touch) == -1 || !started){
          return;
  }
  e.preventDefault();

  swipeTo = delta < 0 ? 'left' : 'right';
Touchend/cancel
  if (e.changedTouches.indexOf(touch) == -1 || !started){
          return;
  }
  e.preventDefault();

  swipeTo = delta < 0 ? 'left' : 'right';

  swipe(swipeTo);
«Страницы»
«Страницы»


                    swipeWidth


       swipeWidth   swipeWidth   swipeWidth
«Страницы»




        -100%   +100%
«Страницы» - таблица


      leftPages.length*100% Pages.length*100%



       100%/Pages.length   100%/Pages.length    100%/Pages.length
Обертка




          .swipe {
                 position: relative;
                 overflow: hidden;
                 height: 300px;
          }
Left/top


.swipe__page {
       overflow: hidden;
       position: absolute;
       left: 0;
       top: 0;
       width: 100%;
       height: 100%;
}
CSS




      .swipe__page_animating {
             transition: transform 200ms linear;
      }
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);
            }
«Страницы»
«Страницы»




        Next left   Current   Next right
Translate - move

                           transform =
                           translate(delta, 0);

                   delta
Translate - move


- swipeWidth + delta   swipeWidth + delta
Touchend - swipe
TransitionEnd - clear
TransitionEnd - clear
Совместимость
Tap-events




             43
Скорость



   touchstart ... touchend … ~300ms … click
                             ~250ms
                             ~150ms
                             ~70ms
                             ~7ms
                                              44
Точность




           45
Внимание




           46
TouchStart


if(
      target.tagName == 'A' || closest(target, 'A')
){
   // Сохраняем событие
}else{
   ignoreEvent = true;
}


                                                      47
TouchEnd


 if( !ignoreEvent ){
     if( abs(startX - newX) < 4 && abs(startY - newY) < 4 ){
         // Создаем событие Click
         Click._fake = true;
         dispatchEvent(Click);
     }
 }


                                                               48
Click

if( !ignoreEvent ){
    if( allowClick(event) ){
        startTap = true;
    }else{
        event.preventDefault();
        event.stopPropagation();
    }
}


                                   49
AllowClick
if( !event ) return true;

if( !event._fake ){

  fired =
    e...vent.target != startTarget ||rget)
  return !( fired || startTap );

}else{
   return true;
}                                            50
AllowClick
if( !event ) return true;

if( !event._fake ){

  fired =
    event.target != startTarget;
  return !( fired || startTap );

}else{
   return true;
}                                  51
Scroll
Вертикальный:
• iOS - JavaScript
• Остальные - Нативный скролл

Горизонтальный:
• iOS - Zoom*
• WebKit - JavaScript
• Остальные - Нативный скролл
                                52
PullToRefresh




                53
PullToRefresh
Scroll



         scroll:move

         scroll:end
                       54
PullToRefresh

                           scroll:move




                            top > 35


        startTime = 0;                   startTime = new Date();



      pulltorefresh:push                    pulltorefresh:pull
PullToRefresh

                                scroll:end
                          pulltorefresh:release




                              new Date() -
                            startTime > 100




     pulltorefresh:push                           pulltorefresh:process
Zoom
Zoom
Zoom
Zoom
transform-origin



           50% 50%   0px 0px
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 )
       );
Zoom



       X = X0 – ( X0 – X1 ) / 2;

       Y = Y0 – ( Y0 – Y1 ) / 2;
Zoom


       documentX =
       ( targetX - scrollX - deltaX ) /
          initialZoom;

       documentY =
       ( targetY - scrollY - deltaY ) /
          initialZoom;
Zoom:touchmove



deltaZoom =
  currentTouchesLength / initialTouchesLength;

currentZoom = initialZoom * deltaZoom;
Zoom:touchmove

deltaZoom =
  currentTouchesLength / initialTouchesLength;
currentZoom = initialZoom * deltaZoom;

left = currentTouch.x –
   ( documentX * currentZoom + deltaX );
top = currentTouch.y –
   ( documentY * currentZoom + deltaY );
Zoom

       content.style['WebkitTransform']

       'translate3d('+left+'px, 0px, 0px)
       scale3d('+currentZoom+', ’
       +currentZoom+', 1)'
СПАСИБО!
         Иван Чашкин, Егор Дыдыкин
           Front-end разработчики
i.chashkin@corp.mail.ru e.dydykin@corp.mail.ru

More Related Content

Viewers also liked

игорь ермаков
игорь ермаковигорь ермаков
игорь ермаковkuchinskaya
 
Rabovoluk presentation yaroslav-2
Rabovoluk presentation yaroslav-2Rabovoluk presentation yaroslav-2
Rabovoluk presentation yaroslav-2kuchinskaya
 
Lapan 20.04 hadoop h-base
Lapan 20.04 hadoop h-baseLapan 20.04 hadoop h-base
Lapan 20.04 hadoop h-basekuchinskaya
 
алексей воропаев
алексей воропаевалексей воропаев
алексей воропаевkuchinskaya
 
денис аникин
денис аникинденис аникин
денис аникинkuchinskaya
 
дмитрий юдин3
дмитрий юдин3дмитрий юдин3
дмитрий юдин3kuchinskaya
 
константин лебедев
константин лебедевконстантин лебедев
константин лебедевkuchinskaya
 
ярослав рабоволюк
ярослав рабоволюкярослав рабоволюк
ярослав рабоволюкkuchinskaya
 
сергей спиридонов
сергей спиридоновсергей спиридонов
сергей спиридоновkuchinskaya
 
борис вольфсон
борис вольфсонборис вольфсон
борис вольфсонkuchinskaya
 
Smirnov reverse-engineering-techforum
Smirnov reverse-engineering-techforumSmirnov reverse-engineering-techforum
Smirnov reverse-engineering-techforumkuchinskaya
 
Smirnov dependency-injection-techforum(1)
Smirnov dependency-injection-techforum(1)Smirnov dependency-injection-techforum(1)
Smirnov dependency-injection-techforum(1)kuchinskaya
 
Kalugin balashov
Kalugin balashovKalugin balashov
Kalugin balashovkuchinskaya
 

Viewers also liked (20)

игорь ермаков
игорь ермаковигорь ермаков
игорь ермаков
 
Sivko
SivkoSivko
Sivko
 
Rabovoluk presentation yaroslav-2
Rabovoluk presentation yaroslav-2Rabovoluk presentation yaroslav-2
Rabovoluk presentation yaroslav-2
 
Lapan 20.04 hadoop h-base
Lapan 20.04 hadoop h-baseLapan 20.04 hadoop h-base
Lapan 20.04 hadoop h-base
 
Treukhov mclags
Treukhov mclagsTreukhov mclags
Treukhov mclags
 
алексей воропаев
алексей воропаевалексей воропаев
алексей воропаев
 
денис аникин
денис аникинденис аникин
денис аникин
 
дмитрий юдин3
дмитрий юдин3дмитрий юдин3
дмитрий юдин3
 
константин лебедев
константин лебедевконстантин лебедев
константин лебедев
 
ярослав рабоволюк
ярослав рабоволюкярослав рабоволюк
ярослав рабоволюк
 
сергей спиридонов
сергей спиридоновсергей спиридонов
сергей спиридонов
 
борис вольфсон
борис вольфсонборис вольфсон
борис вольфсон
 
Platov
PlatovPlatov
Platov
 
A.pleshkov
A.pleshkovA.pleshkov
A.pleshkov
 
Zamyakin
ZamyakinZamyakin
Zamyakin
 
Smirnov reverse-engineering-techforum
Smirnov reverse-engineering-techforumSmirnov reverse-engineering-techforum
Smirnov reverse-engineering-techforum
 
Zacepin
ZacepinZacepin
Zacepin
 
Perepelitsa
PerepelitsaPerepelitsa
Perepelitsa
 
Smirnov dependency-injection-techforum(1)
Smirnov dependency-injection-techforum(1)Smirnov dependency-injection-techforum(1)
Smirnov dependency-injection-techforum(1)
 
Kalugin balashov
Kalugin balashovKalugin balashov
Kalugin balashov
 

Similar to дыдыкин егор

Getting Touchy Feely with the Web
Getting Touchy Feely with the WebGetting Touchy Feely with the Web
Getting Touchy Feely with the WebAndrew Fisher
 
Yahoo presentation: JavaScript Events
Yahoo presentation: JavaScript EventsYahoo presentation: JavaScript Events
Yahoo presentation: JavaScript EventsPeter-Paul Koch
 
openFrameworks – 関数・クラス、オブジェクト指向プログラミング導入 - 多摩美メディアアートII
openFrameworks – 関数・クラス、オブジェクト指向プログラミング導入 - 多摩美メディアアートIIopenFrameworks – 関数・クラス、オブジェクト指向プログラミング導入 - 多摩美メディアアートII
openFrameworks – 関数・クラス、オブジェクト指向プログラミング導入 - 多摩美メディアアートIIAtsushi Tadokoro
 
A Playful Introduction to Rx
A Playful Introduction to RxA Playful Introduction to Rx
A Playful Introduction to RxAndrey Cheptsov
 
The Ring programming language version 1.8 book - Part 66 of 202
The Ring programming language version 1.8 book - Part 66 of 202The Ring programming language version 1.8 book - Part 66 of 202
The Ring programming language version 1.8 book - Part 66 of 202Mahmoud Samir Fayed
 
openFrameworks – パーティクルを動かす、静的配列と動的配列 - 多摩美メディアアートII
openFrameworks – パーティクルを動かす、静的配列と動的配列 - 多摩美メディアアートIIopenFrameworks – パーティクルを動かす、静的配列と動的配列 - 多摩美メディアアートII
openFrameworks – パーティクルを動かす、静的配列と動的配列 - 多摩美メディアアートIIAtsushi Tadokoro
 
Go Beast Mode with Realtime Reactive Interfaces in Angular 2 and Firebase
Go Beast Mode with Realtime Reactive Interfaces in Angular 2 and FirebaseGo Beast Mode with Realtime Reactive Interfaces in Angular 2 and Firebase
Go Beast Mode with Realtime Reactive Interfaces in Angular 2 and FirebaseLukas Ruebbelke
 
Getting touchy - an introduction to touch events / Web Standards Days / Mosco...
Getting touchy - an introduction to touch events / Web Standards Days / Mosco...Getting touchy - an introduction to touch events / Web Standards Days / Mosco...
Getting touchy - an introduction to touch events / Web Standards Days / Mosco...Patrick Lauke
 
#include stdio.h #include stdlib.h #include unistd.h .pdf
 #include stdio.h #include stdlib.h #include unistd.h .pdf #include stdio.h #include stdlib.h #include unistd.h .pdf
#include stdio.h #include stdlib.h #include unistd.h .pdfnipuns1983
 

Similar to дыдыкин егор (20)

C Language Lecture 17
C Language Lecture 17C Language Lecture 17
C Language Lecture 17
 
Getting Touchy Feely with the Web
Getting Touchy Feely with the WebGetting Touchy Feely with the Web
Getting Touchy Feely with the Web
 
Python
PythonPython
Python
 
Yahoo presentation: JavaScript Events
Yahoo presentation: JavaScript EventsYahoo presentation: JavaScript Events
Yahoo presentation: JavaScript Events
 
openFrameworks – 関数・クラス、オブジェクト指向プログラミング導入 - 多摩美メディアアートII
openFrameworks – 関数・クラス、オブジェクト指向プログラミング導入 - 多摩美メディアアートIIopenFrameworks – 関数・クラス、オブジェクト指向プログラミング導入 - 多摩美メディアアートII
openFrameworks – 関数・クラス、オブジェクト指向プログラミング導入 - 多摩美メディアアートII
 
A Playful Introduction to Rx
A Playful Introduction to RxA Playful Introduction to Rx
A Playful Introduction to Rx
 
The Ring programming language version 1.8 book - Part 66 of 202
The Ring programming language version 1.8 book - Part 66 of 202The Ring programming language version 1.8 book - Part 66 of 202
The Ring programming language version 1.8 book - Part 66 of 202
 
Cs580
Cs580Cs580
Cs580
 
I os 15
I os 15I os 15
I os 15
 
C Language Lecture 18
C Language Lecture 18C Language Lecture 18
C Language Lecture 18
 
openFrameworks – パーティクルを動かす、静的配列と動的配列 - 多摩美メディアアートII
openFrameworks – パーティクルを動かす、静的配列と動的配列 - 多摩美メディアアートIIopenFrameworks – パーティクルを動かす、静的配列と動的配列 - 多摩美メディアアートII
openFrameworks – パーティクルを動かす、静的配列と動的配列 - 多摩美メディアアートII
 
Go Beast Mode with Realtime Reactive Interfaces in Angular 2 and Firebase
Go Beast Mode with Realtime Reactive Interfaces in Angular 2 and FirebaseGo Beast Mode with Realtime Reactive Interfaces in Angular 2 and Firebase
Go Beast Mode with Realtime Reactive Interfaces in Angular 2 and Firebase
 
Rxjs kyivjs 2015
Rxjs kyivjs 2015Rxjs kyivjs 2015
Rxjs kyivjs 2015
 
Day 5
Day 5Day 5
Day 5
 
ev
evev
ev
 
The touch events
The touch eventsThe touch events
The touch events
 
Of class3
Of class3Of class3
Of class3
 
Getting touchy - an introduction to touch events / Web Standards Days / Mosco...
Getting touchy - an introduction to touch events / Web Standards Days / Mosco...Getting touchy - an introduction to touch events / Web Standards Days / Mosco...
Getting touchy - an introduction to touch events / Web Standards Days / Mosco...
 
CoW Documentatie
CoW DocumentatieCoW Documentatie
CoW Documentatie
 
#include stdio.h #include stdlib.h #include unistd.h .pdf
 #include stdio.h #include stdlib.h #include unistd.h .pdf #include stdio.h #include stdlib.h #include unistd.h .pdf
#include stdio.h #include stdlib.h #include unistd.h .pdf
 

More from kuchinskaya

More from kuchinskaya (17)

Kharkov
KharkovKharkov
Kharkov
 
Balashov
BalashovBalashov
Balashov
 
Panfilov
PanfilovPanfilov
Panfilov
 
Rabovoluk
RabovolukRabovoluk
Rabovoluk
 
Zagursky
ZagurskyZagursky
Zagursky
 
Haritonov
HaritonovHaritonov
Haritonov
 
Chudov
ChudovChudov
Chudov
 
Bubnov
BubnovBubnov
Bubnov
 
Zenovich
ZenovichZenovich
Zenovich
 
Romanenko
RomanenkoRomanenko
Romanenko
 
Osipov
OsipovOsipov
Osipov
 
Kubasov
KubasovKubasov
Kubasov
 
владимир габриелян
владимир габриелянвладимир габриелян
владимир габриелян
 
чашкин иван
чашкин иванчашкин иван
чашкин иван
 
сумин андрей
сумин андрейсумин андрей
сумин андрей
 
митасов роман
митасов романмитасов роман
митасов роман
 
кренин владимир
кренин владимиркренин владимир
кренин владимир
 

дыдыкин егор

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

Editor's Notes

  1. Свайп, в простонародье – листалка. Позволяет листать из стороны в сторону «страницы» посредствам привычного движения пальцем.(ДЕМО)
  2. Специально для работы с тач устройствами ввода в браузерах реализованы событияНо не все браузеры на тач устройствах их поддерживают
  3. Эмуляция через мышиныеОблом - WP
  4. Стандартная последовательность
  5. Облом – WPПотому swipe реализован только на тач событиях. (ДЕМО)
  6. В тач событие падает информация о касаниях:touches - все касания, ассоциированные с событиемchangedTouches - касания, по которым есть измененияtargetTouches - касания, ассоциированные с target события
  7. Каждому касанию присваивается уникальный идентификатор. В разных браузерах может иметь различные значения, в одних постоянно инкрементируется, в других сбрасывается, когда прикосновений больше нет.Так же объект касания содержит информацию о координатах - относительно вьюпорта (client), экрана (screen) и страницы (page).
  8. проверяем флаг started (не был ли уже начат свайп) и кол-во touches. Если свайп уже идет или toches не один, значит пользователь орудует несколькими пальцами и реагировать на это не надо, а значит return
  9. Запоминаем текущее касание и координатыставим флаг detecting = true, что далее на touchmove надо определить, хотел ли пользователь сделать свайп или он просто прокручивает страницу или тапнул по ссылке
  10. первым делом проверяем, если не стоит ни started, ни detecting, не делаем ничего. Не наш случай
  11. определяем смещение пальца относительно сохраненного касания. Если смещение больше по оси х, чем по у, значит пользователь листает
  12. отменяем поведение по умолчанию, started = trueВ любом случае detecting = false (ДЕМО)
  13. В любом случае detecting = false
  14. отменяем поведение по умолчанию
  15. восстанавливаем интересующее нас касание по идентификатору из changedTouches.Если восстановить не удалось - return
  16. Вычисляем смещение пальца по оси х
  17. Если свайпить некуда, делим смещение на некоторый “коэффициент сопротивления”, делая тем самым вид, что блок как бы сопротивляется движению, чтобы дать пользователю понять, что листать некуда
  18. отрисовываем смещение блока
  19. восстанавливаем интересующее нас касание по идентификатору из changedTouches. Если восстановить не удалось - return
  20. Отменяем действие по-умолчанию (ДЕМО)если этого не сделать, и в блоке к которому мы пролистываем по текущим координатам окажется ссылка, по ней произойдет кли
  21. устанавливаем направление свайпа
  22. Анимируем пролистываниепролистываем блок в нужную сторону
  23. Для того, чтобы сделать листалку, нужно расположить страницы в рядСтраницы же были разбиты на 3 логичные группы:страницы слевацентральная страницы - всегда однаи страницы справа
  24. Каждая из страниц должна быть шириной не больше не меньше родителя.
  25. центральная всегда видна, левые смещены на 100% влево, а правые - на 100% вправо.
  26. Чтобы получить ширину страницы 100% родителя, нужно каким-то образом задать ширину всей таблицы в &lt;колво страниц&gt;*100%, и самим страницам в 100%/&lt;колво страниц&gt;, что без дополнительных JS манипуляций не возможно и грозит погрешностями и неровностями, а так же дополнительными расчетами.
  27. Обертке блока указали высоту, position:relative и overflow:hidden, снизив нагрузку на браузер
  28. нужно максимально обособить страницы друг от друга – каждой страницы указаны position:absolute; и соответствующие координаты и размеры.
  29. Анимируются страницы средствами CSS - transition. (ДЕМО)Если анимировать left, получается очень медленно. Гораздо быстрее работает translate, а еще быстрее translate3d из css-трансформаций.
  30. страницам указан left:0 и оба варианта translateсо значениями смещения по горизонтали -100%, 0 и 100%
  31. Стопки слева и справа
  32. Следующие правая и левая
  33. Изначально анимации выключен, по событию touchmove для страницы устанавливается translate, со значением смещения по горизонтали равным смещению пальца
  34. Одновременно двигаются три страницы - текущая видимая и по странице слева и справа. для правой и левой страниц смещение равноширине страницы с соответствующим положению знаком (для правой плюс, для левой минус) плюс смещение пальца.
  35. По событию touchend или touchcancel страницам устанавливается класс swipe__page_animating, включающий css-анимации, И финальные смещенияЛибо возвращаем все назад, либо пролистываем
  36. На событииtransitionEndотключаются анимацииЗаново выбираются next страницыУстанавливаются новые классы принадлежности к группам
  37. Удаляются установленныеинлайновые стилиИ очищаются установленные флаги вроде startedВозврат к исходному состоянию(ДЕМО)
  38. Например, в случае блока новостей, на примере которого я рассказываю о свайпе, мы сделали привычные всем табы. Пользователь может тапнуть по закладке и перелистнуть страницу.