-
Notifications
You must be signed in to change notification settings - Fork 42
/
DrawingUtils.js
109 lines (92 loc) · 2.77 KB
/
DrawingUtils.js
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
import React from 'react';
import {Path} from 'react-art';
import Vector from 'immutable-vector2d';
import {LINE_WIDTH, GRID_SIZE} from '../../utils/Constants.js';
const utils = {
// credit to: https://stackoverflow.com/questions/55677/how-do-i-get-the-coordinates-of-a-mouse-click-on-a-canvas-element
relMouseCoords(event, node) {
node = React.findDOMNode(node) || node;
var totalOffsetX = 0;
var totalOffsetY = 0;
var x = 0;
var y = 0;
do {
totalOffsetX += node.offsetLeft - node.scrollLeft;
totalOffsetY += node.offsetTop - node.scrollTop;
node = node.offsetParent;
}
while (node);
x = event.pageX - totalOffsetX;
y = event.pageY - totalOffsetY;
return {x, y};
},
makeArtListener: function(f) {
return {
handleEvent: f
};
},
midPoint(p1: Vector, p2: Vector): Vector {
return p1.mix(p2);
},
diff(p1: Vector, p2: Vector): Vector {
return p1.subtract(p2);
},
get2PointConnectorPositionsFor(minLength: number) {
/**
* Given a fixed start point, and a second point being dragged,
* return the connector coordinates for a two-connector element.
*
* @param {Vector} startPoint Fixed starting coordinate
* @param {Vector} dragPoint Coordinate of point being dragged
*/
return function(startPoint: Vector, dragPoint: Vector) {
startPoint = startPoint.snap(GRID_SIZE);
const v = utils.diff(dragPoint, startPoint).minLength(minLength);
return [startPoint, startPoint.add(v).snap(GRID_SIZE)];
};
},
drawRectBetweenTwoPoints(p1: Vector, p2: Vector, width: number) {
const v = utils.diff(p1, p2);
const p = { // perpendicular
x: v.y,
y: -v.x
};
const l: number = v.length();
const r: number = (width / l) / 2;
const np = { // normalised perpendicular
x: p.x * r,
y: p.y * r
};
const cs = [ // corners
{x: p1.x + np.x, y: p1.y + np.y},
{x: p1.x - np.x, y: p1.y - np.y},
{x: p2.x - np.x, y: p2.y - np.y},
{x: p2.x + np.x, y: p2.y + np.y}
];
return new Path()
.moveTo(cs[0].x, cs[0].y)
.lineTo(cs[1].x, cs[1].y)
.lineTo(cs[2].x, cs[2].y)
.lineTo(cs[3].x, cs[3].y)
.close();
},
drawLine(p1: Vector, p2: Vector) {
return utils.drawRectBetweenTwoPoints(p1, p2, LINE_WIDTH);
},
drawCircle(p1: Vector, p2: Vector) {
const v = utils.diff(p1, p2);
const radius = v.length() / 2;
return new Path()
.moveTo(p1.x, p1.y)
.arc(-v.x, -v.y, radius, radius)
.arc(v.x, v.y, radius, radius)
.close();
},
PropTypes: {
Vector: React.PropTypes.instanceOf(Vector),
ArtListener: React.PropTypes.shape({
handleEvent: React.PropTypes.func.isRequired
})
}
};
export default utils;