I am trying to create a sort of plugin or event that css transitions (moves) elements via swipe on ipad. For this I am using so far the brillant working little code snippet of cocco:
(function(D){ var M=Math,abs=M.abs,max=M.max, ce,m,th=20,t,sx,sy,ex,ey,cx,cy,dx,dy,l, f={ touchstart:function(e){ t=e.touches[0]; sx=t.pageX; sy=t.pageY }, touchmove:function(e){ m=1; t=e.touches[0]; ex=t.pageX; ey=t.pageY }, touchend:function(e){ ce=D.createEvent("CustomEvent"); ce.initCustomEvent(m?( max(dx=abs(cx=ex-sx),dy=abs(cy=ey-sy))>th? dx>dy?cx<0?'swl':'swr':cy<0?'swu':'swd':'fc' ):'fc',true,true,e.target); e.target.dispatchEvent(ce); m=0 }, touchcancel:function(e){ m=0 } } for(l in f)D.addEventListener(l,f[l],false) })(document); For the transitions rico st.cruz’ plugin jquery-transit.js is implemented on my site (and jquery of course)
// usage (example)
$("body").on( 'swu', function() { fullscreenSwipeUp = true; $("#Fullscreen").transition( { y: '-100%' }, 900, 'easeInSine' ) } ); // js parts to integrate in a cooler way
var startY; window.addEventListener( 'touchstart', function(e) { e.preventDefault(); startY = e.targetTouches[0].pageY; }, false ); window.addEventListener( 'touchmove', function(e) { e.preventDefault(); // check if transition is going on and animations are ready if ( !fullscreenSwipeUp ) { // find better solution f.e. to dispatch event on fullscreen transition? var diffY = e.changedTouches[0].pageY - startY; // fullscreen transition if ( diffY <= 0 ) { $("#Fullscreen").css( { y: diffY } ); } else { // snap to clean starting value at bottom $("#Fullscreen").css( { y: 0 } ); }; // do something else to indicate that swipe will be concluded when finger leaves // min value based on variable th from custom swipe event if ( diffY < -20 ) { // indicate that swipe will be concluded } else { // indicate that swipe will not conclude }; }; }, false ); // fullscreen fall back to bottom if swipe not concluded window.addEventListener( 'touchend', function(e) { e.preventDefault(); if ( !fullscreenSwipeUp ) { // fall back to starting values / dequeue for smoother transition on second time $("#Fullscreen").dequeue().transition( { y: 0 }, 150, 'easeInSine' ); }; }, false ); Now I see also that in this code various parts overlap each other as the double touch move event from the base custom event and my stuff. It would be so awesome if someone could offer me an idea of how to integrate the two codes. Or maybe something likes this exists? I couldn’t find the right thing.
Thanks for a helping hand!
PS I tried to create a fiddle, also, here: http://jsfiddle.net/Garavani/9zosg3bx/1/ but sadly I am too stupid to make it work with all the external scripts :-(
jquery-transit.js: http://ricostacruz.com/jquery.transit/
EDIT:
So I changed my code in the following way. I guess I was confused between the original swipe event (which incorporates the touch move event also) and what I wanted to do with the element. It works although probably still a mess. I had to set kind of flag to check if the swipe is executed to disable the touch move event temporarily. Is there a better way to do that? Thanks for your patience!
var startY; var swipeY = false; // for condition if condition for swipe is fullfilled var swiped = false; // for check if swipe has been executed window.addEventListener( 'touchstart', function(e) { e.preventDefault(); startY = e.targetTouches[0].pageY; }, false ); window.addEventListener( 'touchmove', function(e) { e.preventDefault(); // check if swipe already executed if ( !swiped ) { // find better solution f.e. to dispatch event when swiped? var diffY = e.changedTouches[0].pageY - startY; // check for final swipe condition if ( diffY < -30 ) { swipeY = true; // do something with an element to indicate swipe will be executed } else { swipeY = false; // do something with an element to indicate swipe will NOT be executed }; }; }, false ); window.addEventListener( 'touchend', function(e) { e.preventDefault(); if ( swipeY ) { swiped = true; // trigger the swipe action } else { // let the element fall back to original state }; }, false ); EDIT 2:
var startY; var swipeY = false; var swiped = false; var wh = $(window).height(); // fullscreen move on touchmove function fm(e) { e.preventDefault(); // check if transition is going on and animations are ready if ( !swiped && ready ) { // !swiped is necessary, also / why? var diffY = e.changedTouches[0].pageY - startY; var scaleY = diffY/wh; // calculate transition intermediate values var osh = 0.91 - ( 0.09 * scaleY ); var ofsc = 0.86 - ( 0.14 * scaleY ); // fullscreen transition if ( diffY <= 0 ) { tfs(osh,[1,-scaleY],ofsc,diffY,0) // an extra module that does the animation with the calculated values } else { // snap to clean starting values at bottom tfs(0.91,[1,0],0.86,0,0) }; // rotate arrow to indicate surpassing minimum touch move leading to swipe if ( diffY < -30 ) { swipeY = true; $arrowDown.addClass('rotation'); } else { swipeY = false; $arrowDown.removeClass('rotation'); }; }; }; // fullscreen swipe function fs(e) { e.preventDefault(); window.removeEventListener( 'touchmove', fm, false ); if ( !swiped ) { // this is necessary, also / why? if ( swipeY ) { $arrowbottomField.trigger('touchstart'); // trigger the full swipe (also available as element direct touch (on touch swiped is set to true in touchstart event handler, also) window.removeEventListener( 'touchend', fs, false ); } else { // fall back of animation to starting values tfs(0.91,[1,0],0.86,0,0); }; }; }; window.addEventListener( 'touchstart', function(e) { e.preventDefault(); startY = e.targetTouches[0].pageY; window.addEventListener( 'touchmove', fm, false ); }, false ); window.addEventListener( 'touchend', fs, false ); Explanation (as good as I can) Thanks Cocco for your patience again. In the meantime I modified the code again. It works :-) I know it will be a mess in your eyes.
On my site (supposed to work also on ipad, but not only) there is a field where you can touch and a fullscreen is moving up covering the whole window (similar to www.chanel.com
Phases:
Phase 1) User taps and swipes (keeping the finger on) The fullscreen div follows his finger.
Pause 2) If a certain distance of the swipe is reached (still with the finger on) a little arrow also turns to indicate: if you leave now, swipe will be executed
Pause 3) still with finger on the distance becomes less than the one to complete the swipe, the arrow turns back
Phase 4) Leave with the finger the distance already covered decides if the fullscreen will move up completely or fall back down (if distance not sufficient)
For the little arrow to turn I could use a class toggle as you told me (way better than what I did! Thanks) but for the rest of the animation not because the values strongly depend on the window size. And the idea of my whole site is that the browser window can have any sizes or relations, all contents adapt themselves (containing horizontal AND vertical centerings at any time)
For mobile phones everything changes completely.
If you want to take a look: www.stefanseifert.com (if you want to see the effect (on ipad) you will have to skip the intro by touching the arrow in the right corner on the bottom of the trailer div)
I know that there is tons of other stuff that is note state of the art programming (to say this very carefully :-) but in a way it works. And I can not afford to hire a programmer for weeks to redo everything. ;-) It’s kind of learning by doing (for as you can guess I never programmed before in my life ;-) so I am very thankful for every bit of information and help to do little things better.
If someone will pass here I will get some down votes for sure :-) Thanks Cocco Merry Christmas!