2

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

我尝试添加其他事件处理程序,调用 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>
4

1 回答 1

0

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

于 2013-01-07T17:01:54.927 回答