由touchmove事件指示的自定义滑动事件 [英] custom swipe event indicated by touchmove event

查看:89
本文介绍了由touchmove事件指示的自定义滑动事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图创建一种插件或事件css转换(移动)元素通过在ipad上滑动。为此,我使用到目前为止cocco的brillant工作的小代码片段:

 (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? (dx = abs(cx = ex-sx),dy = abs(cy = ey-sy))> th?
dx> dy?cx <0?swl':'swr':cy < ?'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);

对于转换rico st.cruz'plugin jquery-transit.js在我的网站jquery当然)



//用法(示例)

  $ (body)。on('swu',function(){
fullscreenSwipeUp = true;
$(#Fullscreen)。transition({y:' - 100%'} 'easeInSine')
});

到目前为止很好。
现在我的想法是指示可能的向上滑动一个额外的触摸移动事件,移动元素,同时手指敲击。我成功地添加了以下js:



// js部分以更冷的方式集成

  var startY; 

window.addEventListener('touchstart',function(e){
e.preventDefault();
startY = e.targetTouches [0] .pageY;
},false);

window.addEventListener('touchmove',function(e){
e.preventDefault();
//检查转换是否正在进行,动画是否准备就绪
if(!fullscreenSwipeUp){//在全屏转换上找到更好的解决方案fe调度事件?

var diffY = e.changedTouches [0] .pageY - startY;

//全屏转换
if(diffY< = 0){
$(#Fullscreen)css({y:diffY});
} else {
/ / snap to clean starting value at bottom
$(#Fullscreen)。css({y:0});
};
//做其他事情,结束时手指离开
//根据来自自定义滑动事件的变量th的最小值
if(diffY <-20){
//表示滑动将结束
} else {
//表示滑动将不会结束
};

};
},false);

//如果滑动不结束,全屏返回到底部
window.addEventListener('touchend',function(e){
e.preventDefault();
if(!fullscreenSwipeUp){
//返回到起始值/出列以便第二次平滑过渡
$(#Fullscreen)。dequeue()。transition({y:0},150 ,'easeInSine');
};
},false);

现在我还看到,在这段代码中,各个部分彼此重叠,作为双触摸移动事件基本自定义事件和我的东西。如果有人能给我一个如何集成两个代码的想法,这将是如此真棒。或者也许有这样的东西存在?我找不到正确的东西。



感谢您的帮助!



一个小提琴,也在这里:



添加一些行....

 (函数(D){
var M = Math,abs = M.abs,max = M.max,
ce,m,th = 20,t,sx, sy,ex,ey,cx,cy,dx,dy,l,
T,// < - THE TARGET
f = {
touchstart:function(e){
t = e.touches [0];
sx = t.pageX;
sy = t.pageY;
T = e.target; T.classList.add('sw') /< - 添加SWIPES的自定义类别
},
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;
T.classList.remove('sw'); // < - REMOVE THE CLASS
},
touchcancel:function(e){
m = 0
}
}
for )D.addEventListener(l,f [1],false)
})(document);

现在定义css类

  element.sw {
background-color:yellow;
}

使用您的元素上的移动设备的正确>

 元素{
background-color:green;
-webkit-transition:background-color 200ms ease;
}

这是一个简单和肮脏的解决方案,它的工作原理。只是保持简单。



该类将仅适用于定义的元素。 ;)



选项2



忘记上面的代码...

这里是另一种表演者方式,使用bounce做一个snap动画。



有点复杂...并使用鼠标..用触摸事件替换鼠标事件。



http://jsfiddle.net/xgkbjwxb/



并有更多数据点



http://jsfiddle.net/xgkbjwxb/1/



注意:请勿在移动设备中使用jquery或复杂的js插件。



额外



由于在没有触摸界面的PC上工作确实有问题,我添加了一些线,强迫鼠标根据我的功能要求来模拟触摸。



http://jsfiddle.net/agmyjwb0/



EDIT



此代码应该按照您想要的...



http://jsfiddle.net/xgkbjwxb/3/ p>

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' )
} );

So far so good. Now my idea was to indicate the possible „swipe up" with an additional touch move event that moves the element along while the finger tap is going on. And I succeeded in doing so adding the following js:

// 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 -> „more"). Additionally it is (on ipad) possible to swipe on the whole body to do the same thing.

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!

解决方案

The code is actually made for low cpu devices , high performance .. leaving out complex calculations inside the touchmove. Anyway to animate your elements (between touchstart & touchend) a simple solution is to use css (not jquery or other resourceintensive plugins).

then just think logically... you can't determine in wich direction you swipe at the touchstart... you can do that at the touchend event after doing some math. OR while touchmove wich destroys the whole code, as mentioned above.

OPTION 1 (simple & high performance)

DEMO

http://jsfiddle.net/z7s8k9r4/

Add some lines....

(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,
 T,  //<- THE TARGET
 f={
  touchstart:function(e){
    t=e.touches[0];
    sx=t.pageX;
    sy=t.pageY;
    T=e.target; T.classList.add('sw'); //<- ADD A CUSTOM CLASS FOR SWIPES
  },
  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;
    T.classList.remove('sw');  //<- REMOVE THE CLASS
  },
  touchcancel:function(e){
    m=0
  }
 }
 for(l in f)D.addEventListener(l,f[l],false)
})(document);

now define the css class

element.sw{
 background-color:yellow;
}

use the proper (HW) animation for mobile devices on your element

element{
 background-color:green;
 -webkit-transition:background-color 200ms ease;
}

this is a simple and dirty solution , it works. just keep it simple.

the class will apply only on defined elements. ;)

OPTION 2

forget the code above...

Here is another "performant" way to do a "snap" animation using "bounce".

the code is a little more complex... and uses the mouse.. replace the mouse events with touch events.

http://jsfiddle.net/xgkbjwxb/

and with more data points

http://jsfiddle.net/xgkbjwxb/1/

note: don't use jquery or complex js plugins in mobile devices.

Extra

As it's really problematic to work on pc without a touch interface i added some lines that force the mouse to simulate touches based on my function requisites.

http://jsfiddle.net/agmyjwb0/

EDIT

this code should do what you want...

http://jsfiddle.net/xgkbjwxb/3/

这篇关于由touchmove事件指示的自定义滑动事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆