您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 

116 行
4.1 KiB

define(function (require, exports, module) {
var Bezier = require('graphic/bezier');
var BezierPoint = require('graphic/bezierpoint');
var Vector = require('graphic/vector');
var Pen = require('graphic/pen');
function mid(a, b) {
return (a + b) / 2;
}
function getSnapPoints( snaper ) {
if(snaper.getSnapPoints) {
return snaper.getSnapPoints();
}
var box = snaper.getRenderBox();
var x1 = box.x, x2 = box.x + box.width,
y1 = box.y, y2 = box.y + box.height,
xm = mid(x1, x2), ym = mid(y1, y2);
return [
{ x: xm, y: y1, type: 'top' }, // top
{ x: x2, y: ym, type: 'right' }, // right
{ x: xm, y: y2, type: 'bottom' }, // bottom
{ x: x1, y: ym, type: 'left' } // left
];
}
var DIR_NORMALS = {
top: new Vector(0, -1),
left: new Vector(-1, 0),
bottom: new Vector(0, 1),
right: new Vector(1, 0)
};
function fillNormal( snapPoint ) {
if(snapPoint.normal) {
return;
}
snapPoint.normal = DIR_NORMALS[snapPoint.type] || DIR_NORMALS.left;
}
return require('core/class').createClass("SnapCurve", {
base: Bezier,
constructor: function( start, end ) {
this.callBase();
this.setStartSnaper( start );
this.setEndSnaper( end );
this.init();
this.updateConnection();
},
init: function() {
this.addPoint(this.startBesierPoint = new BezierPoint());
this.addPoint(this.endBesierPoint = new BezierPoint());
this.stroke(new Pen('red', 3));
},
bindSnaper: function( snaper ) {
var me = this;
snaper.on('shapeupdate', function() {
me.updateConnection();
});
},
setStartSnaper: function( snaper ) {
this.start = snaper;
this.bindSnaper(snaper);
},
setEndSnaper: function( snaper ) {
this.end = snaper;
this.bindSnaper(snaper);
},
isReady: function() {
return !!(this.start && this.end);
},
calcEndPoints: function() {
var startEnds = getSnapPoints(this.start),
endEnds = getSnapPoints(this.end);
var nearStart, nearEnd, minDistance = Number.MAX_VALUE;
var i, j, startEnd, endEnd, distance;
// 寻找最近的粘附点
// 暴力解法:可优化但不必要,因为点集不会很大
for( i = 0; i < startEnds.length; i++) {
for( j = 0; j < endEnds.length; j++) {
distance = Math.abs(startEnds[i].x - endEnds[j].x) + Math.abs(startEnds[i].y - endEnds[j].y) * 0.5; //Vector.fromPoints( startEnds[i], endEnds[j] ).length();
if(distance < minDistance) {
minDistance = distance;
nearStart = startEnds[i];
nearEnd = endEnds[j];
}
}
}
return {
start: new Vector(nearStart.x, nearStart.y),
end: new Vector(nearEnd.x, nearEnd.y)
};
},
updateConnection: function() {
if(!this.isReady()) {
return false;
}
var endPoints = this.calcEndPoints(),
startEnd = endPoints.start,
endEnd = endPoints.end;
fillNormal(startEnd);
fillNormal(endEnd);
var pointVector = Vector.fromPoints( startEnd, endEnd );
var forward = pointVector.project(startEnd.normal);
var backward = pointVector.reverse().project(endEnd.normal);
forward = startEnd.add(forward.multipy(0.5));
backward = endEnd.add(backward.multipy(0.5));
this.startBesierPoint.setVertex(startEnd.x, startEnd.y);
this.startBesierPoint.setForward(forward.x, forward.y);
this.endBesierPoint.setVertex(endEnd.x, endEnd.y);
this.endBesierPoint.setBackward(backward.x, backward.y);
}
});
});