サイズ変更可能な親シェイプとサイズ変更可能な子シェイプを接続線で作成する必要がある小さなプロジェクトで作業しています。KinecticJS で行いました。しかし、形状のサイズ変更時に x1、x2 (開始コネクタ) および x2、y2 (終了コネクタ) を計算する際に問題があります。
この計算は、関数 addConnection にあります。
var x1 = parentNode.getX() + rectParent.getWidth()/2;
var y1 = parentNode.getY() + rectParent.getHeight()/2;
var x2 = childNode.getX() + rectChild.getWidth()/2;
var y2 = childNode.getY() + rectChild.getHeight()/2;
作業コードをhttp://jsfiddle.net/geremora/nxDNH/に置きました
私のJavascriptコード:
var stage = new Kinetic.Stage({
container: 'container',
width: 400,
height: 400
});
var groupRoot = new Kinetic.Group({
x: 100,
y: 50,
draggable: true,
});
var layer = new Kinetic.Layer();
layer.add(groupRoot);
stage.add(layer);
newRect(groupRoot);
var groupChild = new Kinetic.Group({
x: 270,
y: 100,
draggable: true
});
layer.add(groupChild);
newRect(groupChild);
var con = addConnection(groupRoot, groupChild);
layer.add(con);
con.moveToBottom();
stage.draw();
function newRect(group){
var rect = new Kinetic.Rect({
x: 0,
y: 0,
width: 50,
height: 50,
fill: 'blue',
stroke: 'black',
strokeWidth: 1,
name:'rect'
});
group.add(rect);
addAnchor(group, rect.x, rect.y, 'topLeft');
addAnchor(group, rect.getWidth(), rect.y, 'topRight');
addAnchor(group, rect.getWidth(), rect.getHeight(), 'bottomRight');
addAnchor(group, rect.x, rect.getHeight(), 'bottomLeft');
group.on('dragstart', function() {
this.moveToTop();
});
stage.draw();
}
function update(activeAnchor) {
var group = activeAnchor.getParent();
var topLeft = group.get('.topLeft')[0];
var topRight = group.get('.topRight')[0];
var bottomRight = group.get('.bottomRight')[0];
var bottomLeft = group.get('.bottomLeft')[0];
var rect = group.get('.rect')[0];
var anchorX = activeAnchor.getX();
var anchorY = activeAnchor.getY();
switch (activeAnchor.getName()) {
case 'topLeft':
topRight.setY(anchorY);
bottomLeft.setX(anchorX);
break;
case 'topRight':
topLeft.setY(anchorY);
bottomRight.setX(anchorX);
break;
case 'bottomRight':
bottomLeft.setY(anchorY);
topRight.setX(anchorX);
break;
case 'bottomLeft':
bottomRight.setY(anchorY);
topLeft.setX(anchorX);
break;
}
rect.setPosition(topLeft.getPosition());
var width = topRight.getX() - topLeft.getX();
var height = bottomLeft.getY() - topLeft.getY();
if(width && height) {
rect.setSize(width, height);
}
}
function addAnchor(group, x, y, name) {
var stage = group.getStage();
var layer = group.getLayer();
var anchor = new Kinetic.Circle({
x: x,
y: y,
stroke: '#666',
fill: '#ddd',
strokeWidth: 1,
radius: 5,
name: name,
draggable: true,
dragOnTop: false
});
anchor.on('dragmove', function() {
update(this);
layer.draw();
});
anchor.on('mousedown touchstart', function() {
group.setDraggable(false);
this.moveToTop();
});
anchor.on('dragend', function() {
group.setDraggable(true);
layer.draw();
});
anchor.on('mouseover', function() {
var layer = this.getLayer();
document.body.style.cursor = 'pointer';
this.setStrokeWidth(4);
layer.draw();
});
anchor.on('mouseout', function() {
var layer = this.getLayer();
document.body.style.cursor = 'default';
this.setStrokeWidth(2);
layer.draw();
});
group.add(anchor);
}
function addConnection(parentNode, childNode){
var connector = new Kinetic.Line({
drawFunc: function (canvas) {
var rectParent = parentNode.get('.rect')[0];
var rectChild = childNode.get('.rect')[0];
var ctx = canvas.getContext();
var x1 = parentNode.getX() + rectParent.getWidth()/2;
var y1 = parentNode.getY() + rectParent.getHeight()/2;
var x2 = childNode.getX() + rectChild.getWidth()/2;
var y2 = childNode.getY() + rectChild.getHeight()/2;
ctx.save();
ctx.strokeStyle = "red";
ctx.lineWidth = 3;
ctx.beginPath();
ctx.moveTo(x1, y1);
ctx.lineTo(x2, y2);
ctx.stroke();
ctx.restore();
},
points: [1, 1, 1, 3],
stroke: "red",
strokeWidth: 2,
lineCap: 'round',
lineJoin: 'round',
opacity: 1,
draggable: false
});
return connector;
}