如何在dragmove中将一个组分成两个子组?

时间:2014-05-04 21:07:42

标签: javascript kineticjs

我有一个包含许多矩形的组。当我指向该组的矩形并拖动它时,我想在该点分离该组并具有两个子组。我在下面的jsfiddle示例中设法做了一个简单的例子,但是我使用的是dblclick事件。发生的是我通过使用(var shape = evt.targetNode;)获取矩形的位置然后重新创建这两个组。我通过发射2个事件来做到这一点。

我的问题是:

  1. 可以通过触发单个事件 - 拖拉事件来完成此操作吗?这样,每当用户开始拖动组时,根据拖动的方向,要自动分离的组'。 更重要的是,我想知道每当用户开始拖动组时,根据拖动的方向,即可自动分离的组。
  2. 对于这个版本,我使用的是kinetic-v5.0.1.min.js。但是,当我使用最新的kineticjs版本(kinetic-v5.1.0.min.js)时,由于某种原因(var shape = evt.targetNode;)不再有效。我在这里错过了什么吗?
  3. jsfiddle链接: http://jsfiddle.net/maik18/tbYLe/16/

        group.on('dblclick', function() {
    
        var groups = stage.find('Group');
    
        var rects = stage.find('Rect');
        var group1= groups[0].getChildren().slice(0,globalPosition);
        var group2= groups[0].getChildren().slice(globalPosition,6);
    
    
    
        var newGroup1 = new Kinetic.Group({
            x: group1[0].getAbsolutePosition().x,
            y: group1[0].getAbsolutePosition().y-40,
            draggable:true
        });
    
        var newGroup2 = new Kinetic.Group({
            x: group2[0].getAbsolutePosition().x-globalPosition*100,
            y: group2[0].getAbsolutePosition().y-40,
            draggable: true
        });
    
    
        for (var i=0; i < group1.length; i++){
            newGroup1.add(group1[i]);
        }
        for (var i=0; i < group2.length; i++){
            newGroup2.add(group2[i]);
        }
    
        writeMessage(newGroup2.getChildren()[0].getAbsolutePosition().x);
        shapesLayer.add(newGroup1);
        shapesLayer.add(newGroup2);
    
        groups[0].getChildren().splice(0,6);
        shapesLayer.draw();
    
        groups[0].destroy();
    
    });
    

    运行示例: http://jsfiddle.net/maik18/tbYLe/16/embedded/result/

1 个答案:

答案 0 :(得分:2)

  1. 是的,您可以使用dragmove事件将一个组细分为两组:

    • 确定拖动是向左还是向右移动。

    • 将孩子分为两组(1)应该被拖拽的孩子。 (2)应该在初始位置保持静止的儿童。

    • 创建一个新组,将固定的孩子放入该新组中。

    • 继续拖动原始组中的其他子项(无需创建2个新组 - 只需重新使用原始组,因为您已经拖动它了。)

  2. “使用事件委派时,evt.targetNode已更改为evt.target”(请参阅​​版本5.1.0的更改日志:https://github.com/ericdrowell/KineticJS/wiki/Change-Log

  3. 注意:您可以使用stage.getIntersection(mousePosition)来确定鼠标下面的矩形。

    这是带注释的代码和演示:http://jsfiddle.net/m1erickson/8fuPJ/

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="utf-8">
    <script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
    <script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v5.1.0.min.js"></script>
    <style>
    body{padding:20px;}
    #container{
      border:solid 1px #ccc;
      margin-top: 10px;
      width:350px;
      height:350px;
    }
    </style>        
    <script>
    $(function(){
    
        // create a stage and a layer
        var stage = new Kinetic.Stage({
            container: 'container',
            width: 350,
            height: 350
        });
        var layer = new Kinetic.Layer();
        stage.add(layer);
    
    
        // make a template group
        // all new groups will be a clone of this template group
        // this template group knows how to sub-divide its children
        var templateGroup=new Kinetic.Group({
          draggable:true,
        });
    
        //
        templateGroup.on('dragstart',function(){
    
            // save the x-coordinate where the mouse started the drag
            // this x is used to determine if the drag is right or left
            var pos=stage.getPointerPosition();   
            this.startX=pos.x;
    
            // determine which rectangle is under the mouse
            // this rect will be the dividing point between this and a new group
            this.dragRect=stage.getIntersection(pos);
    
            // create a new group cloned from the templateGroup
            // (the templateGroup has code necessary to divide itself)
            if(this.dragRect){
                this.newGroup=templateGroup.clone();
                this.newGroup.position(this.initialPosition);
                this.newGroup.initialPosition=this.initialPosition;
                this.isDragging=true;
            }
    
        });
    
        //
        templateGroup.on('dragmove',function(){
    
            // performance: 
            // just do this function once
            // isDragging will be false if this Fn has already been done once
            if(!this.isDragging){return;}
    
            var pos=stage.getPointerPosition();
    
            // performance: 
            // just return if the drag hasn't gone right or left at least 1 pixel
            if(pos.x==this.startX){return;}
    
            // clear the isDragging flag
            this.isDragging=false;
    
            // flag indicating whether the mouse moved left or right
            var isRight=(pos.x>this.startX);
    
            // get the x coordinate of the rect under the cursor
            // this "x" is used to divide the current group in two
            var dragRectX=this.dragRect.x();
    
            // an array that will hold children to be move to the new group
            var newGroupChildren=[];
    
            // get the children of this group
            var children=this.getChildren();
    
            // enumerate all children and add any "non-dragging" rects to
            // the array of children to be moved to the new group
            children.each(function(child){
                if(isRight && child.x()<dragRectX){
                    newGroupChildren.push(child);
                }
                if(!isRight && child.x()>dragRectX){
                    newGroupChildren.push(child);
                }
            });
    
            // move "stationary" children from this group to the new group
            for(var i=0;i<newGroupChildren.length;i++){
                newGroupChildren[i].moveTo(this.newGroup);
            }
    
            // add the new group to the layer
            layer.add(this.newGroup);
    
            // redraw the layer
            layer.draw();
        });
    
        //
        templateGroup.on("dragend",function(){
    
            // store the resting position of this group
            // any future new subgroups will be positioned at this position
            this.initialPosition=this.position();
        });
    
    
        // add a group to the stage
        var group=templateGroup.clone();
        group.initialPosition=templateGroup.position();
        layer.add(group);
    
    
        // testing...add 6 boxes to the group
        for(var i=0;i<6;i++){
            var rect=new Kinetic.Rect({
                id:i,
                x:i*30+50,
                y:100,
                width:25,
                height:20,
                fill:randomColor(),
                stroke: 'black',
                strokeWidth: 2,
            });
            group.add(rect);
        }
        layer.draw();
    
        // utility function to create a random color
        function randomColor(){ 
            return('#'+Math.floor(Math.random()*16777215).toString(16));
        }
    
    
    }); // end $(function(){});
    
    </script>       
    </head>
    <body>
        <h4>Drag a rectangle to create a sub-group</h4>
        <div id="container"></div>
    </body>
    </html>