0

我正在使用 KineticJS 开发一个简单的图表编辑器。我想为调色板区域使用两个单独的画布(其中包含许多代表我可能创建的网络的不同节点的 Kinetic.Groups)和图表区域,我可以通过拖放从调色板中添加节点,然后将各个节点之间的连接添加为特定的锚点。我无法弄清楚从(固定)Kinetic.Groups 的调色板画布到包含图表区域的另一个画布的拖放过程。我猜我需要为调色板对象触发 dragstart 事件(尽管我不希望它们本身是可拖动的),然后执行一些操作,例如创建可以拖动的调色板对象的不透明副本,

可以将组拖到临时画布边界之外吗?当我开始从调色板拖动时,也许我需要生成一个图像,将该图像拖过来,然后在放入图表区域时创建另一个组。

是否有人知道任何可能为我指明正确方向的示例,或者谁可以对所需过程提供一些见解(甚至代码)。我搜索了 KineticJS 示例,但找不到足够的内容让我继续前进。

4

1 回答 1

1

这是将节点从源调色板拖到目标组中的一种方法:

小提琴:http: //jsfiddle.net/m1erickson/xtVyL/

在此处输入图像描述

网络节点由小图标表示(它们是非常小的动态图像对象)。

用户可以将任何图标从源调色板拖到任何目标组。

这些组只是画布上定义的区域,但可以是 Kinetc.Groups 以获得更大的灵活性。

在 dragend 事件期间,将在目标组中创建拖动图标的新副本。

dragend 事件完成后,原始的调色板图标会自动从新创建的重复图标中拖动到目标组周围(但不能在该组之外)。

这是代码和小提琴:http: //jsfiddle.net/m1erickson/xtVyL/

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Prototype</title>
    <script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
    <script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v4.5.5.min.js"></script>

<style>
#container{
  border:solid 1px #ccc;
  margin-top: 10px;
  width:350px;
  height:350px;
}
</style>        
<script>
$(function(){

    var stage = new Kinetic.Stage({
        container: 'container',
        width: 350,
        height: 350
    });
    var layer = new Kinetic.Layer();
    stage.add(layer);


    // image loader

    var imageURLs=[];
    var imagesOK=0;
    var imgs=[];
    imageURLs.push("https://dl.dropboxusercontent.com/u/139992952/stackoverflow/tempPC.png");
    imageURLs.push("https://dl.dropboxusercontent.com/u/139992952/stackoverflow/tempServer.png");
    imageURLs.push("https://dl.dropboxusercontent.com/u/139992952/stackoverflow/tempRouter.png");
    loadAllImages();

    function loadAllImages(callback){
        for (var i = 0; i < imageURLs.length; i++) {
            var img = new Image();
            imgs.push(img);
            img.onload = function(){ 
                imagesOK++; 
                if (imagesOK==imageURLs.length ) {
                    start();
                }
            }; 
            img.src = imageURLs[i];
        }      
    }


    // top icon positions
    var nextIconX=20;
    var nextIconY=20;

    // define groups
    var groups=[];
    groups.push({x:0,y:100,w:175,h:250,fill:"skyblue"});
    groups.push({x:175,y:100,w:175,h:250,fill:"cornsilk"});
    // add boundary info to each group
    // draw colored rect to show group area
    for(var i=0;i<groups.length;i++){
        var g=groups[i];
        g.left=g.x;
        g.right=g.x+g.w;
        g.top=g.y;
        g.bottom=g.y+g.h;
        var rect=new Kinetic.Rect({
            x:g.x,
            y:g.y,
            width:g.w,
            height:g.h,
            fill:g.fill,
            stroke:"gray"
        });
        layer.add(rect);
    }
    // hittest for each group
    function groupHit(x,y){
        for(var i=0;i<groups.length;i++){
            var g=groups[i];
            if(x>g.left && x<g.right && y>g.top && y<g.bottom){return(i);}
        }
        return(-1);
    }


    function start(){
        makePaletteIcon(imgs[0]);
        makePaletteIcon(imgs[1]);
        makePaletteIcon(imgs[2]);
        layer.draw();
    }


    function makePaletteIcon(img){

        // make an icon that stays in the pallette tray
        var fixedIcon=newImage(nextIconX,nextIconY,img,false);
        layer.add(fixedIcon);


        // make an icon that is dragged from the tray to a group
        var dragIcon=makeDraggableIcon(nextIconX,nextIconY,img);
        layer.add(dragIcon);

        // calc the next icon position
        nextIconX+=(img.width+20);

    }


    function makeDraggableIcon(x,y,img){

        var i=newImage(x,y,img,true);
        // 
        i.trayX=x;
        i.trayY=y;
        //
        i.setOpacity(0.50);

        i.on("dragend",function(){

            var x=this.getX();
            var y=this.getY();

            // if this pallette icon was not dropped in a group
            // put the icon back in the tray and return
            var hit=groupHit(x,y);
            if(hit==-1){
                this.setPosition(this.trayX,this.trayY);
                return;
            }

            // add a copy of this icon to the drop group  
            var component=newImage(x,y,this.getImage(),true);

            // set drag limits
            var group=groups[hit];
            component.maxDragLeft=group.left;
            component.maxDragRight=group.right;
            component.maxDragTop=group.top;
            component.maxDragBottom=group.bottom;

            // limit component dragging to inside the assigned group
            component.setDragBoundFunc(function(pos) {
                var xx=pos.x;
                var yy=pos.y;
                var w=this.getWidth();
                var h=this.getHeight();
                if(pos.x<this.maxDragLeft){xx=this.maxDragLeft;}
                if(pos.x+w>this.maxDragRight){xx=this.maxDragRight-w;}
                if(pos.y<this.maxDragTop){yy=this.maxDragTop;}
                if(pos.y+h>this.maxDragBottom){yy=this.maxDragBottom-h;}
                return{ x:xx, y:yy };
            });

            layer.add(component);

            // move the dragIcon back into the pallette tray
            this.setPosition(this.trayX,this.trayY);

            layer.draw();

        });

        return(i);
    }

    // make a new Kinetic.Image
    function newImage(x,y,img,isDraggable){
        var i=new Kinetic.Image({
            image:img,
            x: x,
            y: y,
            width: img.width,
            height: img.height,
            draggable:isDraggable
        });
        return(i);
    }


}); // end $(function(){});

</script>       
</head>

<body>
    <p>Drag any icon from top into blue or yellow group</p>
    <div id="container"></div>
</body>
</html>
于 2013-09-10T02:39:05.027 回答