如何强制Canvas事件处理程序完成更新

时间:2013-01-06 02:57:22

标签: javascript html5 event-handling html5-canvas kineticjs

我正在尝试使用HTLM 5 Canvas KineticJS来构建一个包含列表的框。我想给盒子一个把它拖动的手柄,我也希望能够拖动列表项目。我已将其实现为Kinetic.Group。下面我的精简示例中的列表项是很少的Kinetic.Text对象。当我完成拖动时,我无法获取要更新的对象的属性。在Chrome或Firefox中运行它,当我拖动其中一个文本对象框并将其删除时,我的dragend事件处理程序将其从组中删除,因此它应该从屏幕上消失。相反,它一直保持可见,直到我在屏幕上的某个元素上出现,然后它就消失了。

我尝试添加其他事件处理程序,调用drawhit和drawcene函数,并使用simulate函数生成模拟鼠标单击。这些确实有一些效果,但我找不到任何组合,在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>

1 个答案:

答案 0 :(得分:0)

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