/
Connect.sketchplugin
137 lines (115 loc) · 5.13 KB
/
Connect.sketchplugin
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
// Sketch Plugin: AEFlowchart - Connect (ctrl shift c)
// Source: github.com/tadija/AEFlowchart
// Version: 1.0
@import 'AEFlowchart.js'
var stepName = "Connector";
/* call AEFlowchart main function with custom name and lineShape function */
connectSteps(drawAllConnections);
function drawAllConnections(selection)
{
// sort selection from top to bottom steps
var sortedSelection = [];
var loop = [selection objectEnumerator];
while (item = [loop nextObject]) {
sortedSelection.push(item);
}
sortedSelection = sortedSelection.sort(sortByPosition);
// draw connection between every two steps
for (var i = 0; i < sortedSelection.length; i++) {
// skip last step (there is no step after to connect)
if ((i + 1) < sortedSelection.length) {
var twoSteps = [sortedSelection[i], sortedSelection[i + 1]];
drawOneConnection(twoSteps);
}
}
}
function drawOneConnection(twoSteps)
{
// get steps to connect
var firstStep = twoSteps[0];
var secondStep = twoSteps[1];
// get connectionsGroup position
var parentGroup = [firstStep parentGroup];
var connectionsGroup = getConnectionsGroup(parentGroup);
var connectionsGroupFrame = [connectionsGroup frame];
var connectionsGroupX = [connectionsGroupFrame x];
var connectionsGroupY = [connectionsGroupFrame y];
// get frames of steps
var firstStepFrame = [firstStep frame];
var secondStepFrame = [secondStep frame];
// get points (always reset to origin of the artboard by substracting connectionsGroup position)
var firstStepBottom = [firstStepFrame maxY] - connectionsGroupY;
var firstStepRight = [firstStepFrame maxX] - connectionsGroupX;
var firstStepHorizontalMiddle = [firstStepFrame midX] - connectionsGroupX;
var firstStepVerticalMiddle = [firstStepFrame midY] - connectionsGroupY;
var secondStepTop = [secondStepFrame minY] - connectionsGroupY;
var secondStepLeft = [secondStepFrame minX] - connectionsGroupX;
var secondStepHorizontalMiddle = [secondStepFrame midX] - connectionsGroupX;
var secondStepVerticalMiddle = [secondStepFrame midY] - connectionsGroupY;
var horizontalSpacingHalf = (secondStepLeft - firstStepRight) / 2;
var verticalSpacingHalf = (secondStepTop - firstStepBottom) / 2;
var horizontalMiddleDifference = firstStepHorizontalMiddle - secondStepHorizontalMiddle;
var verticalMiddleDifference = firstStepVerticalMiddle - secondStepVerticalMiddle;
// create NSBezierPath
var lineBezierPath = [NSBezierPath bezierPath];
if (firstStepBottom < secondStepTop) {
// draw vertical connection
[lineBezierPath moveToPoint:CGPointMake(firstStepHorizontalMiddle, firstStepBottom)];
// tolerate some pixels in horizontalMiddleDifference
if (Math.abs(horizontalMiddleDifference) > 2.0) {
[lineBezierPath lineToPoint:CGPointMake(firstStepHorizontalMiddle, firstStepBottom + verticalSpacingHalf)];
[lineBezierPath lineToPoint:CGPointMake(secondStepHorizontalMiddle, firstStepBottom + verticalSpacingHalf)];
[lineBezierPath lineToPoint:CGPointMake(secondStepHorizontalMiddle, secondStepTop)];
} else {
[lineBezierPath lineToPoint:CGPointMake(firstStepHorizontalMiddle, secondStepTop)];
}
} else {
// draw horizontal connection
[lineBezierPath moveToPoint:CGPointMake(firstStepRight, firstStepVerticalMiddle)];
// tolerate some pixels in verticalMiddleDifference
if (Math.abs(verticalMiddleDifference) > 2.0) {
[lineBezierPath lineToPoint:CGPointMake(firstStepRight + horizontalSpacingHalf, firstStepVerticalMiddle)];
[lineBezierPath lineToPoint:CGPointMake(firstStepRight + horizontalSpacingHalf, secondStepVerticalMiddle)];
[lineBezierPath lineToPoint:CGPointMake(secondStepLeft, secondStepVerticalMiddle)];
} else {
[lineBezierPath lineToPoint:CGPointMake(secondStepLeft, firstStepVerticalMiddle)];
}
}
// create vector line
var lineShape = [[MSShapeGroup alloc] init];
[lineShape setBezierPath: lineBezierPath];
[lineShape setName:[firstStep name] + " -> " + [secondStep name]];
styleType = "layerStyles";
if(doesStyleExist(stepName, lineShape, styleType) == false) {
// log(stepName + " style doesn't exist so create it");
createBorderStyle(stepName, lineShape, connectLineColor, connectLineThickness, connectStartArrow, connectStartArrowType, connectEndArrow, connectEndArrowType);
}
// add line shape to connectionsGroup
[connectionsGroup addLayers:[lineShape]];
// deselect steps
[firstStep setIsSelected:false];
[secondStep setIsSelected:false];
}
function sortByPosition(a,b)
{
var sortOrder;
if ([[a frame] maxY] < [[b frame] minY] || [[b frame] maxY] < [[a frame] minY]) {
// sort from top to bottom
sortOrder = [[a frame] top] - [[b frame] top];
} else {
// sort from left to right
sortOrder = [[a frame] left] - [[b frame] left];
}
return sortOrder;
}
function getConnectionsGroup(parentGroup)
{
var connectionsGroup = [parentGroup layerWithID:"AEConnections"];
// create group if not exists
if (connectionsGroup === null) {
connectionsGroup = [parentGroup addLayerOfType:"group"];
[connectionsGroup setName:"AEConnections"];
[connectionsGroup setIsLocked:true];
}
return connectionsGroup;
}