KineticJS:降低阻力事件的敏感性

时间:2014-02-13 13:58:34

标签: javascript drag-and-drop touch kineticjs

背景:我正在尝试构建一个应用,用户可以通过同时单击两个动态形状来执行操作,但也可以在画布上拖动单个形状自如。我意识到KineticJS不支持多点触控(但是)但在解决这个问题之前我遇到了另一个问题。

问题: 我正在使用的触摸屏(平板电脑27“Helium,在Windows 8中使用Chrome)似乎很难很好地解决触摸事件。这意味着在Kinetic中点击(并按住)一个形状会触发拖动事件,而不是单个点击或点按事件。当发生这种情况时,我可以看到手指下方几个像素周围的形状,这告诉我触摸事件是移动位置,即使手指停留在同一个地方。

我想要的是什么: 一种调整拖动事件灵敏度的方法,以便它们仅在距当前形状位置的距离达到一定像素数时触发。理想情况下,点击事件将触发,然后在特定阈值后执行dragstart。我假设最初停止发射阻力事件也意味着当我按下按钮时,形状将在我的手指下稍微移动。

我在KineticJS源代码中有一个窥探,但我似乎无法看到应该实现这样的代码。


解决了!请参阅下面的解决方案。

3 个答案:

答案 0 :(得分:3)

此问题已通过在KineticJS项目的最近提交中引入dragDistance属性(https://github.com/ericdrowell/KineticJS/commit/0b93e21e0b9e11165dfed7574dbafa0ae2a144e0,或请求https://github.com/ericdrowell/KineticJS/pull/725获取拉取请求)来解决。

要使用该功能,只需在触发之前将拖动必须超过的值(以像素为单位)分配给形状或组的dragDistance属性。低于此阈值的touchStart事件不会触发dragStart,这意味着tap事件现在在触摸场景中更有用。

var rect = new Kinetic.Rect({
    draggable: true,
    dragDistance: 5
});

答案 1 :(得分:1)

基本上我认为你必须绑定点击目标,并且只有在一段时间后发生某事时才做某事:

/* #########################
   ########## HTML #########
   ######################### */

<div id='target'></div>

/* #########################
   ###### JAVASCRIPT #######
   ######################### */

var mousedownID = -1;  
var timer = 0;  /* tenth of second */      
var timeToDrag = 25;


var mousedown = function(event) {
  if(mousedownID==-1)  
     mousedownID = setInterval(whilemousedown, 100);
}

var mouseup = function(event) {
   if(mousedownID!=-1) {
     clearInterval(mousedownID);
     mousedownID=-1;
   }

}

var whilemousedown = function() {
  timer += 1;
  if( timer > timeToDrag ) {
     /* Call drag */
     /* if you want you can force mouseup calling mouseup() function */
  }
}

$('#target').mousedown(mousedown);
$('#targer').mouseup(mouseup);

您可以查看fiddle。希望这是有帮助的!

修改

同样,您可以绑定touchstart和touchend事件:

$('#target').bind("touchstart", mousedown);
$('#target').bind("touchend", mouseup);

答案 2 :(得分:0)

您可以在*事件之前使用Kinetic来阻止拖动,直到达到特定的拖动距离。

但是,当前版本的KineticJS已经删除了所有适用于您情况的before*事件。

您可以查找以前的版本并在*事件之前重新安装。

<强>替代地

在touchstart上,您可以告诉节点在一小段时间内停止收听事件。

通过这种方式,节点不会在短时间内收听,并且不会通过开始拖动来响应您无意中的手指抽搐。

这里untested-probably-needs-tweeking-code关闭了很长一段时间的听力。

在每个节点上添加属性以定义延迟:

// delay 100ms when a delay is requested

myNode.delayAmount=100;

// initialize with no delay (delayUntil==0)

myNode.delayUntil=0;

添加一个touchstart处理程序,该处理程序将停止侦听此节点,直到将来不久

myNode.on("touchstart"){ 

    this.listening(false);

    this.delayUntil=new Date().now()+this.delayAmount;

    debounce(this);

}

定期检查延迟时间是否已过。如果是,请转回来

function debounce(node){

    var delayUntil=node.delayUntil;

    if(delayUntil==0){return;}

    if((new Date().now())<delayUntil){
        requestAnimationFrame(debounce);
        return;
    }

    node.isListening(true);

    node.delayUntil=0;

    }

}