背景:我正在尝试构建一个应用,用户可以通过同时单击两个动态形状来执行操作,但也可以在画布上拖动单个形状自如。我意识到KineticJS不支持多点触控(但是)但在解决这个问题之前我遇到了另一个问题。
问题: 我正在使用的触摸屏(平板电脑27“Helium,在Windows 8中使用Chrome)似乎很难很好地解决触摸事件。这意味着在Kinetic中点击(并按住)一个形状会触发拖动事件,而不是单个点击或点按事件。当发生这种情况时,我可以看到手指下方几个像素周围的形状,这告诉我触摸事件是移动位置,即使手指停留在同一个地方。
我想要的是什么: 一种调整拖动事件灵敏度的方法,以便它们仅在距当前形状位置的距离达到一定像素数时触发。理想情况下,点击事件将触发,然后在特定阈值后执行dragstart。我假设最初停止发射阻力事件也意味着当我按下按钮时,形状将在我的手指下稍微移动。
我在KineticJS源代码中有一个窥探,但我似乎无法看到应该实现这样的代码。
解决了!请参阅下面的解决方案。
答案 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;
}
}