2013-01-06 55 views
2

我正在尝试使用HTLM 5 Canvas KineticJS来构建一个包含列表的框。我想给这个盒子提供一个拖动它的句柄,我也希望能够拖动列表项目。我已经实施了这个Kinetic.Group。下面我精简的例子中的列表项是小Kinetic.Text对象。我无法在完成拖动时更新对象的属性。在Chrome或Firefox中运行它时,当拖动其中一个文本对象框并将其放下时,我的dragend事件处理程序会将其从组中移除,因此应该从屏幕上消失。相反,它保持可见,直到我屏蔽了屏幕上的元素,然后消失。如何强制Canvas事件处理程序完成更新

我试着添加其他事件处理程序,调用drawhit和drawscene函数,并使用模拟函数来生成模拟鼠标点击。这些确实有一些效果,但是我找不到任何组合,在dragend处理程序结束时将所有内容都保持在正确的状态。例如,在某些情况下,该框的拖动手柄不起作用。在我的代码的其他版本中,会出现类似的奇怪效果,所有这些似乎都需要额外的鼠标点击才能使对象完成更新。

我已经在Canvas源代码中查找了一些会强制重绘和在线搜索的函数,但是没有发现任何似乎用于此目的的函数。理想情况下,Canvas会自动执行此操作,所以我怀疑我缺少一些明显的步骤。任何想法可能是什么?

这里是我的javascript:

var stage = new Kinetic.Stage({ 
    container: 'container', 
    width: 500, 
    height: 200 
}); 

var layer = new Kinetic.Layer(); 

var group = new Kinetic.Group({ 
    x: 50, 
    y: 50 
}); 

var box = new Kinetic.Polygon({ 
    points: [0, 20, 0, 100, 200, 100, 200, 0, 20, 0], 
    stroke: 'blue', 
    strokeWidth: 2 
}); 
group.add(box);  

var handle = new Kinetic.Polygon({ 
    points: [0, 0, 0, 20, 20, 0], 
    fill: 'blue', 
    stroke: 'blue', 
    strokeWidth: 2 
}); 
group.add(handle); 

handle.on('mouseover', function() { 
    group.setDraggable(true); 
    document.body.style.cursor = 'pointer'; 
    }); 

handle.on('mouseout', function() { 
    group.setDraggable(false); 
    document.body.style.cursor = 'default'; 
});  

var colors = ['red', 'orange', 'yellow']; 
for(var n = 0; n < 3; n++) { 
    (function() { 
     var i = n; 
     var item = new Kinetic.Text({ 
      x: 20 + i * 25, 
      y: 20, 
      width: 20, 
      height: 10, 
      fill: colors[i], 
      draggable: true, 
      id: i, 
     }); 

     group.add(item); 

     item.on('dragend', function() { 
      console.log('item dragend'); 
      id = this.getId(); 
      var children = group.getChildren(); 
      var len = children.length; 
      for(var i = 2; i < len; i++) { 
       if (id == children[i].getId()) { 
        children.splice(i,1); 
        break; 
       }; 
      } 
     }); 
    })(); 
}; 

layer.add(group); 
stage.add(layer); 

我用这个HTML来运行它:

<!DOCTYPE HTML> 
<html> 
    <head> 
    <style> 
     body { 
     margin: 0px; 
     padding: 0px; 
     } 
    </style> 
    </head> 
    <body> 
    <div id="container"></div> 
     <script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/v4.2.0/kinetic-v4.2.0.js"></script>  
    <script src="/Users/tsnichols/Documents/workspace/WebScheduler/listgroup.js"></script> 
    </body> 
</html> 
+0

找到了解决办法,我想。我在dragend事件处理程序的结尾处调用stage.draw()。 –

+0

当您自己找到解决方案时,请随时发布详细的答案。回答你自己的问题并不是在stackoverflow.com上皱起眉头 - 它甚至被鼓励! – Philipp

+0

为了防止性能优化,您应该使用layer.draw(),因为它只会重绘一层而不是整个舞台。 (这只有在你有多个图层时才有用) – SoluableNonagon

回答

0

是啊,stage.draw()是最简单的解决方案,但如果你有多个图层并正在使用一堆动画,您应该使用layer.draw()绘制单个图层,以获得性能。

相关问题