123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116 |
- 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);
- }
- });
- });
|