简体   繁体   English

KineticJS-具有连接的可拖动形状

[英]KineticJS - draggable shape with connections

I'm pretty new to KineticJS and have a problem with a draggable shape (circle) and a line, which connects this shape with another. 我对KineticJS相当陌生,并且在可拖动形状(圆形)和直线之间存在问题,该直线将这种形状与另一个形状连接起来。 I'm not able to redraw the lines after moving the draggable shape. 移动可拖动形状后,我无法重绘线条。 Maybe one of you can give me a hint. 也许你们之一能给我提示。

Here is my code: 这是我的代码:

<!DOCTYPE html>
<html>
<head>
<title></title>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script type="text/javascript" src="kinetic.js"></script>
<link href='http://fonts.googleapis.com/css?family=Open+Sans+Condensed:300' rel='stylesheet' type='text/css'>
<style type="text/css">
    html, body {
        font-family: 'Open Sans Condensed', Arial, sans-serif;
        font-size: 14px;
        background: #EFEFEF;
        width: 100%;
        height: 100%;
    }

    h1 {
        text-align: center;
        font-size: 30px;
    }

    #canvas {
        display: block;
        background: white;
        border: 1px solid #CCC;
        margin: 50px auto;
        width: 700px;
        height: 500px;
    }
</style>
</head>
<body>


<h1>kinetic.js test</h1>

<div id="canvas"></div>

<script defer="defer">

    /**
     * get circle center coordinates
     *
     * @desc    gets coordinates of circle center
     * @param   shapeId     -   id of circle
     * @returns {object}    -   object with x and y coordinates
     */
    function getCircleCenterCoordinates(shapeId) {

        var shape = getShapeById(shapeId);

        if(typeof shape == 'object') {

            return {x: shape.shape.attrs.x, y: shape.shape.attrs.y}

        }

    }


    /**
     * get shape by id
     *
     * @desc    searches for given shape id and returns the matching
     * @param   shapeId     -   id of the circle
     * @returns {*}
     */
    function getShapeById(shapeId) {

        var result = jQuery.grep(shapes, function(e) { return e.id == shapeId; });

        if(result.length == 1) {

            return result[0];

        } else {

            return null;

        }

    }


    /**
     * draw
     *
     * @desc    draw shapes
     * @retuns  {void}
     */
    function draw() {

        // add shapes to the layer and register event listeners
        for(var i = 0; i < shapes.length; i++) {

            var shapeObj = shapes[i];


            // add shape to layer
            circleLayer.add(shapeObj.shape);

            // register event listeners
            for(var n = 0; n < shapeObj.events.length; n++) {

                var eventObj = shapeObj.events[n];

                shapeObj.shape.on(eventObj.type, eventObj.callback);

            }

            // draw connections
            for(var m = 0; m < shapeObj.connections.length; m++) {

                var connectionObj = shapeObj.connections[m];

                // get ids
                var fromId  = shapeObj.id;
                var toId    = connectionObj.to;

                // check if connection is already drawn
                if(fromId > toId) {

                    // do not draw it again
                    continue;

                }

                // get coordinates
                var fromCoordinatesObj  = getCircleCenterCoordinates(fromId);
                var toCoordinatesObj    = getCircleCenterCoordinates(toId);

                // check coordinates
                if(typeof fromCoordinatesObj != 'object' || typeof toCoordinatesObj != 'object') {

                    // was not able to get valid coordinates
                    continue;

                }

                // update / set line points for this connection
                connectionObj.line.attrs.points = [fromCoordinatesObj.x, fromCoordinatesObj.y, toCoordinatesObj.x, toCoordinatesObj.y];

                // add line to layer
                connectorLayer.add(connectionObj.line);

            }

        }


        // add the layers to the stage
        stage.add(connectorLayer);
        stage.add(circleLayer);

    }


    /**
     * init shapes and layers
     * -------------------------------------------------------------------------------------------------------
     */

    // create stage
    var stage = new Kinetic.Stage({
        container: 'canvas',
        width: 700,
        height: 500
    });


    // create layers
    var circleLayer     = new Kinetic.Layer();
    var connectorLayer  = new Kinetic.Layer();


    // define shapes
    var shapes = [

        {
            id:     1001,
            label:  'me',
            shape:  new Kinetic.Circle({
                x: stage.getWidth() / 2 - 200,
                y: stage.getHeight() / 2 + 100,
                radius: 70,
                fill: '#DDD',
                stroke: '#EFEFEF',
                strokeWidth: 10,
                draggable: true
            }),
            events: [
                {type: 'mouseover', callback: function() { console.log('over 1');}}
            ],
            connections: [
                {to: 2001, line: new Kinetic.Line({stroke: '#333', strokeWidth: 2})},
                {to: 3001, line: new Kinetic.Line({stroke: '#333', strokeWidth: 2})},
                {to: 4001, line: new Kinetic.Line({stroke: '#333', strokeWidth: 2})}
            ]

        },
        {
            id:     2001,
            label:  'you',
            shape:  new Kinetic.Circle({
                x: stage.getWidth() / 2 + 200,
                y: stage.getHeight() / 2 + 100,
                radius: 70,
                fill: '#DDD',
                stroke: '#EFEFEF',
                strokeWidth: 10,
                draggable: true
            }),
            events: [
                {type: 'mouseover', callback: function() { console.log('over 2');}}
            ],
            connections: [
                {to: 1001, line: new Kinetic.Line({stroke: '#333', strokeWidth: 2})},
                {to: 3001, line: new Kinetic.Line({stroke: '#333', strokeWidth: 2})},
                {to: 4001, line: new Kinetic.Line({stroke: '#333', strokeWidth: 2})}
            ]
        },
        {
            id:     3001,
            label:  'her',
            shape:  new Kinetic.Circle({
                x: stage.getWidth() / 2,
                y: stage.getHeight() / 2 - 100,
                radius: 70,
                fill: '#DDD',
                stroke: '#EFEFEF',
                strokeWidth: 10,
                draggable: true
            }),
            events: [
                {type: 'mouseover', callback: function() { console.log('over 3');}}
            ],
            connections: [
                {to: 1001, line: new Kinetic.Line({stroke: '#333', strokeWidth: 2})},
                {to: 2001, line: new Kinetic.Line({stroke: '#333', strokeWidth: 2})}
            ]
        },
        {
            id:     4001,
            label:  'his',
            shape:  new Kinetic.Circle({
                x: 100,
                y: 150,
                radius: 70,
                fill: '#DDD',
                stroke: '#EFEFEF',
                strokeWidth: 10,
                draggable: true
            }),
            events: [
                {type: 'mouseover', callback: function() { console.log('over 4');}},
                {type: 'dragend', callback: function() { console.log(this.getPosition()); console.log(shapes[3]);  }}
            ],
            connections: [
                {to: 1001, line: new Kinetic.Line({stroke: '#333', strokeWidth: 2})},
                {to: 2001, line: new Kinetic.Line({stroke: '#333', strokeWidth: 2})}
            ]
        }

    ];


    // draw shapes
    draw();

</script>

Here's how to keep 2 nodes connected with a Kinetic.Line. 这是保持2个节点与Kinetic.Line连接的方法。

  • Create a Kinetic.Line with points set to connect the 2 nodes you wish to connect. 创建一个Kinetic.Line,其点设置为连接要连接的2个节点。

  • Listen for dragmove events on the 2 nodes you wish to connect. 在您希望连接的2个节点上侦听dragmove事件。

  • On dragmove of either node, reset the connecting line's points to again connect to the 2 nodes. 在任一节点的拖动移动中,重置连接线的点以再次连接到2个节点。

Something like this... 像这样

NodeA.on('dragmove',function(){
    connectorAB.points([NodeA.x(),nodeA.y(),nodeB.x(),nodeB.y()]);
    layer.draw();
});

// same thing for NodeB

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM