|
@@ -25,144 +25,144 @@
|
25
|
25
|
*/
|
26
|
26
|
|
27
|
27
|
(function hand() { //Code isolation
|
28
|
|
- const selectorStates = {
|
29
|
|
- pointing: 0,
|
30
|
|
- selecting: 1,
|
31
|
|
- moving: 2
|
32
|
|
- }
|
33
|
|
- var selected = null;
|
34
|
|
- var selected_els = [];
|
35
|
|
- var selectionRect = createSelectorRect();
|
36
|
|
- var selectionRectTranslation;
|
37
|
|
- var translation_elements = [];
|
38
|
|
- var selectorState = selectorStates.pointing;
|
|
28
|
+ const selectorStates = {
|
|
29
|
+ pointing: 0,
|
|
30
|
+ selecting: 1,
|
|
31
|
+ moving: 2
|
|
32
|
+ }
|
|
33
|
+ var selected = null;
|
|
34
|
+ var selected_els = [];
|
|
35
|
+ var selectionRect = createSelectorRect();
|
|
36
|
+ var selectionRectTranslation;
|
|
37
|
+ var translation_elements = [];
|
|
38
|
+ var selectorState = selectorStates.pointing;
|
39
|
39
|
var last_sent = 0;
|
40
|
40
|
|
41
|
|
- function inRect(x ,y , rect) {
|
42
|
|
- return (x>=rect.x && x<=rect.x+rect.width) &&
|
43
|
|
- (y>=rect.y && y>=rect.w+rect.height)
|
44
|
|
- }
|
45
|
|
-
|
46
|
|
- function intersectRect(rect1 , rect2) {
|
47
|
|
- return !(
|
48
|
|
- (rect1.x+rect1.width<=rect2.x) ||
|
49
|
|
- (rect2.x+rect2.width<=rect1.x) ||
|
50
|
|
- (rect1.y+rect1.height<=rect2.y) ||
|
51
|
|
- (rect2.y+rect2.height<=rect1.y)
|
52
|
|
- )
|
53
|
|
- }
|
54
|
|
-
|
55
|
|
- function getParentMathematics(el) {
|
56
|
|
- var target
|
57
|
|
- var a = el
|
58
|
|
- var els = [];
|
59
|
|
- while (a) {
|
60
|
|
- els.unshift(a);
|
61
|
|
- a = a.parentElement;
|
|
41
|
+ function inRect(x, y, rect) {
|
|
42
|
+ return (x >= rect.x && x <= rect.x + rect.width) &&
|
|
43
|
+ (y >= rect.y && y >= rect.w + rect.height)
|
62
|
44
|
}
|
63
|
|
- var parentMathematics = els.find(el => el.getAttribute("class") === "MathElement");
|
64
|
|
- if ((parentMathematics) && parentMathematics.tagName === "svg") {
|
65
|
|
- target = parentMathematics;
|
|
45
|
+
|
|
46
|
+ function intersectRect(rect1, rect2) {
|
|
47
|
+ return !(
|
|
48
|
+ (rect1.x + rect1.width <= rect2.x) ||
|
|
49
|
+ (rect2.x + rect2.width <= rect1.x) ||
|
|
50
|
+ (rect1.y + rect1.height <= rect2.y) ||
|
|
51
|
+ (rect2.y + rect2.height <= rect1.y)
|
|
52
|
+ )
|
66
|
53
|
}
|
67
|
|
- return target ?? el;
|
68
|
|
- }
|
69
|
54
|
|
70
|
|
- function createSelectorRect() {
|
71
|
|
- var shape = Tools.createSVGElement("rect");
|
72
|
|
- shape.id = "selectionRect";
|
73
|
|
- shape.x.baseVal.value = 0;
|
74
|
|
- shape.y.baseVal.value = 0;
|
75
|
|
- shape.width.baseVal.value = 0;
|
76
|
|
- shape.height.baseVal.value = 0;
|
77
|
|
- shape.setAttribute("stroke", "black");
|
78
|
|
- shape.setAttribute("stroke-width", 1);
|
79
|
|
- shape.setAttribute("vector-effect", "non-scaling-stroke");
|
80
|
|
- shape.setAttribute("fill", "none");
|
81
|
|
- shape.setAttribute("stroke-dasharray", "5 5");
|
82
|
|
- shape.setAttribute("opacity", 1);
|
83
|
|
- Tools.svg.appendChild(shape);
|
84
|
|
- return shape;
|
85
|
|
- }
|
|
55
|
+ function getParentMathematics(el) {
|
|
56
|
+ var target
|
|
57
|
+ var a = el
|
|
58
|
+ var els = [];
|
|
59
|
+ while (a) {
|
|
60
|
+ els.unshift(a);
|
|
61
|
+ a = a.parentElement;
|
|
62
|
+ }
|
|
63
|
+ var parentMathematics = els.find(el => el.getAttribute("class") === "MathElement");
|
|
64
|
+ if ((parentMathematics) && parentMathematics.tagName === "svg") {
|
|
65
|
+ target = parentMathematics;
|
|
66
|
+ }
|
|
67
|
+ return target ?? el;
|
|
68
|
+ }
|
86
|
69
|
|
87
|
|
- function startMovingElements(x, y, evt) {
|
88
|
|
- evt.preventDefault();
|
89
|
|
- selectorState = selectorStates.moving;
|
90
|
|
- selected = {x: x, y: y};
|
91
|
|
- // Some of the selected elements could have been deleted
|
92
|
|
- selected_els = selected_els.filter(el=>{
|
93
|
|
- return Tools.svg.getElementById(el.id) !== null
|
94
|
|
- });
|
95
|
|
- translation_elements = selected_els.map(el => {
|
96
|
|
- let tmatrix = get_translate_matrix(el);
|
97
|
|
- return {x: tmatrix.e, y: tmatrix.f}
|
98
|
|
- });
|
99
|
|
- {
|
100
|
|
- let tmatrix = get_translate_matrix(selectionRect);
|
101
|
|
- selectionRectTranslation = {x: tmatrix.e, y: tmatrix.f};
|
|
70
|
+ function createSelectorRect() {
|
|
71
|
+ var shape = Tools.createSVGElement("rect");
|
|
72
|
+ shape.id = "selectionRect";
|
|
73
|
+ shape.x.baseVal.value = 0;
|
|
74
|
+ shape.y.baseVal.value = 0;
|
|
75
|
+ shape.width.baseVal.value = 0;
|
|
76
|
+ shape.height.baseVal.value = 0;
|
|
77
|
+ shape.setAttribute("stroke", "black");
|
|
78
|
+ shape.setAttribute("stroke-width", 1);
|
|
79
|
+ shape.setAttribute("vector-effect", "non-scaling-stroke");
|
|
80
|
+ shape.setAttribute("fill", "none");
|
|
81
|
+ shape.setAttribute("stroke-dasharray", "5 5");
|
|
82
|
+ shape.setAttribute("opacity", 1);
|
|
83
|
+ Tools.svg.appendChild(shape);
|
|
84
|
+ return shape;
|
102
|
85
|
}
|
103
|
|
- }
|
104
|
86
|
|
105
|
|
- function startSelector(x, y , evt) {
|
106
|
|
- evt.preventDefault();
|
107
|
|
- selected = {x: x, y: y};
|
108
|
|
- selected_els= [];
|
109
|
|
- selectorState = selectorStates.selecting;
|
110
|
|
- selectionRect.x.baseVal.value = x;
|
111
|
|
- selectionRect.y.baseVal.value = y;
|
112
|
|
- selectionRect.width.baseVal.value = 0;
|
113
|
|
- selectionRect.height.baseVal.value = 0;
|
114
|
|
- selectionRect.style.display = "";
|
115
|
|
- tmatrix = get_translate_matrix(selectionRect);
|
116
|
|
- tmatrix.e = 0;
|
117
|
|
- tmatrix.f = 0;
|
118
|
|
- }
|
|
87
|
+ function startMovingElements(x, y, evt) {
|
|
88
|
+ evt.preventDefault();
|
|
89
|
+ selectorState = selectorStates.moving;
|
|
90
|
+ selected = { x: x, y: y };
|
|
91
|
+ // Some of the selected elements could have been deleted
|
|
92
|
+ selected_els = selected_els.filter(el => {
|
|
93
|
+ return Tools.svg.getElementById(el.id) !== null
|
|
94
|
+ });
|
|
95
|
+ translation_elements = selected_els.map(el => {
|
|
96
|
+ let tmatrix = get_translate_matrix(el);
|
|
97
|
+ return { x: tmatrix.e, y: tmatrix.f }
|
|
98
|
+ });
|
|
99
|
+ {
|
|
100
|
+ let tmatrix = get_translate_matrix(selectionRect);
|
|
101
|
+ selectionRectTranslation = { x: tmatrix.e, y: tmatrix.f };
|
|
102
|
+ }
|
|
103
|
+ }
|
119
|
104
|
|
|
105
|
+ function startSelector(x, y, evt) {
|
|
106
|
+ evt.preventDefault();
|
|
107
|
+ selected = { x: x, y: y };
|
|
108
|
+ selected_els = [];
|
|
109
|
+ selectorState = selectorStates.selecting;
|
|
110
|
+ selectionRect.x.baseVal.value = x;
|
|
111
|
+ selectionRect.y.baseVal.value = y;
|
|
112
|
+ selectionRect.width.baseVal.value = 0;
|
|
113
|
+ selectionRect.height.baseVal.value = 0;
|
|
114
|
+ selectionRect.style.display = "";
|
|
115
|
+ tmatrix = get_translate_matrix(selectionRect);
|
|
116
|
+ tmatrix.e = 0;
|
|
117
|
+ tmatrix.f = 0;
|
|
118
|
+ }
|
120
|
119
|
|
121
|
|
- function calculateSelection() {
|
122
|
|
- var scale = Tools.drawingArea.getCTM().a;
|
123
|
|
- var selectionTBBox = selectionRect .transformedBBox(scale);
|
124
|
|
- return Array.from(Tools.drawingArea.children).filter(el => {
|
125
|
|
- return transformedBBoxIntersects(
|
126
|
|
- selectionTBBox,
|
127
|
|
- el.transformedBBox(scale)
|
128
|
|
- )
|
129
|
|
- });
|
130
|
|
- }
|
131
|
120
|
|
132
|
|
- function moveSelection(x, y) {
|
133
|
|
- var dx = x - selected.x;
|
134
|
|
- var dy = y - selected.y;
|
135
|
|
- var msgs = selected_els.map((el,i) =>{
|
136
|
|
- return {
|
137
|
|
- type: "update",
|
138
|
|
- id: el.id,
|
139
|
|
- deltax: dx+translation_elements[i].x,
|
140
|
|
- deltay: dy+translation_elements[i].y
|
141
|
|
- }
|
142
|
|
- })
|
143
|
|
- var msg = {
|
144
|
|
- _children: msgs
|
145
|
|
- };
|
146
|
|
- {
|
147
|
|
- let tmatrix = get_translate_matrix(selectionRect);
|
148
|
|
- tmatrix.e = dx + selectionRectTranslation.x;
|
149
|
|
- tmatrix.f = dy + selectionRectTranslation.y;
|
|
121
|
+ function calculateSelection() {
|
|
122
|
+ var scale = Tools.drawingArea.getCTM().a;
|
|
123
|
+ var selectionTBBox = selectionRect.transformedBBox(scale);
|
|
124
|
+ return Array.from(Tools.drawingArea.children).filter(el => {
|
|
125
|
+ return transformedBBoxIntersects(
|
|
126
|
+ selectionTBBox,
|
|
127
|
+ el.transformedBBox(scale)
|
|
128
|
+ )
|
|
129
|
+ });
|
150
|
130
|
}
|
151
|
|
- var now = performance.now();
|
152
|
|
- if (now - last_sent > 70) {
|
153
|
|
- last_sent = now;
|
154
|
|
- Tools.drawAndSend(msg);
|
155
|
|
- } else {
|
156
|
|
- draw(msg);
|
|
131
|
+
|
|
132
|
+ function moveSelection(x, y) {
|
|
133
|
+ var dx = x - selected.x;
|
|
134
|
+ var dy = y - selected.y;
|
|
135
|
+ var msgs = selected_els.map((el, i) => {
|
|
136
|
+ return {
|
|
137
|
+ type: "update",
|
|
138
|
+ id: el.id,
|
|
139
|
+ deltax: dx + translation_elements[i].x,
|
|
140
|
+ deltay: dy + translation_elements[i].y
|
|
141
|
+ }
|
|
142
|
+ })
|
|
143
|
+ var msg = {
|
|
144
|
+ _children: msgs
|
|
145
|
+ };
|
|
146
|
+ {
|
|
147
|
+ let tmatrix = get_translate_matrix(selectionRect);
|
|
148
|
+ tmatrix.e = dx + selectionRectTranslation.x;
|
|
149
|
+ tmatrix.f = dy + selectionRectTranslation.y;
|
|
150
|
+ }
|
|
151
|
+ var now = performance.now();
|
|
152
|
+ if (now - last_sent > 70) {
|
|
153
|
+ last_sent = now;
|
|
154
|
+ Tools.drawAndSend(msg);
|
|
155
|
+ } else {
|
|
156
|
+ draw(msg);
|
|
157
|
+ }
|
157
|
158
|
}
|
158
|
|
- }
|
159
|
159
|
|
160
|
|
- function updateRect(x,y, rect) {
|
161
|
|
- rect.x.baseVal.value = Math.min(x,selected.x);
|
162
|
|
- rect.y.baseVal.value = Math.min(y,selected.y);
|
163
|
|
- rect.width.baseVal.value = Math.abs(x-selected.x);
|
164
|
|
- rect.height.baseVal.value = Math.abs(y-selected.y);
|
165
|
|
- }
|
|
160
|
+ function updateRect(x, y, rect) {
|
|
161
|
+ rect.x.baseVal.value = Math.min(x, selected.x);
|
|
162
|
+ rect.y.baseVal.value = Math.min(y, selected.y);
|
|
163
|
+ rect.width.baseVal.value = Math.abs(x - selected.x);
|
|
164
|
+ rect.height.baseVal.value = Math.abs(y - selected.y);
|
|
165
|
+ }
|
166
|
166
|
|
167
|
167
|
function get_translate_matrix(elem) {
|
168
|
168
|
// Returns the first translate or transform matrix or makes one
|
|
@@ -183,58 +183,57 @@
|
183
|
183
|
return translate.matrix;
|
184
|
184
|
}
|
185
|
185
|
|
186
|
|
- function draw(data) {
|
187
|
|
- if (data._children) {
|
188
|
|
- batchCall(draw, data._children);
|
189
|
|
- }
|
190
|
|
- else {
|
191
|
|
- switch (data.type) {
|
192
|
|
- case "update":
|
193
|
|
- var elem = Tools.svg.getElementById(data.id);
|
194
|
|
- if (!elem) throw new Error("Mover: Tried to move an element that does not exist.");
|
195
|
|
- var tmatrix = get_translate_matrix(elem);
|
196
|
|
- tmatrix.e = data.deltax || 0;
|
197
|
|
- tmatrix.f = data.deltay || 0;
|
198
|
|
- break;
|
199
|
|
- default:
|
200
|
|
- throw new Error("Mover: 'move' instruction with unknown type. ", data);
|
|
186
|
+ function draw(data) {
|
|
187
|
+ if (data._children) {
|
|
188
|
+ batchCall(draw, data._children);
|
|
189
|
+ }
|
|
190
|
+ else {
|
|
191
|
+ switch (data.type) {
|
|
192
|
+ case "update":
|
|
193
|
+ var elem = Tools.svg.getElementById(data.id);
|
|
194
|
+ if (!elem) throw new Error("Mover: Tried to move an element that does not exist.");
|
|
195
|
+ var tmatrix = get_translate_matrix(elem);
|
|
196
|
+ tmatrix.e = data.deltax || 0;
|
|
197
|
+ tmatrix.f = data.deltay || 0;
|
|
198
|
+ break;
|
|
199
|
+ default:
|
|
200
|
+ throw new Error("Mover: 'move' instruction with unknown type. ", data);
|
|
201
|
+ }
|
201
|
202
|
}
|
202
|
203
|
}
|
203
|
|
- }
|
204
|
204
|
|
205
|
|
- function clickSelector(x ,y , evt) {
|
206
|
|
- var scale = Tools.drawingArea.getCTM().a
|
207
|
|
- selectionRect = selectionRect ?? createSelectorRect();
|
208
|
|
- if (pointInTransformedBBox([x,y],selectionRect.transformedBBox(scale))) {
|
209
|
|
- startMovingElements(x, y, evt);
|
210
|
|
- } else if (Tools.drawingArea.contains(evt.target))
|
211
|
|
- {
|
212
|
|
- selectionRect.style.display = "none";
|
213
|
|
- selected_els = [getParentMathematics(evt.target)];
|
214
|
|
- startMovingElements(x, y, evt);
|
215
|
|
- } else {
|
216
|
|
- startSelector(x, y, evt);
|
|
205
|
+ function clickSelector(x, y, evt) {
|
|
206
|
+ var scale = Tools.drawingArea.getCTM().a
|
|
207
|
+ selectionRect = selectionRect ?? createSelectorRect();
|
|
208
|
+ if (pointInTransformedBBox([x, y], selectionRect.transformedBBox(scale))) {
|
|
209
|
+ startMovingElements(x, y, evt);
|
|
210
|
+ } else if (Tools.drawingArea.contains(evt.target)) {
|
|
211
|
+ selectionRect.style.display = "none";
|
|
212
|
+ selected_els = [getParentMathematics(evt.target)];
|
|
213
|
+ startMovingElements(x, y, evt);
|
|
214
|
+ } else {
|
|
215
|
+ startSelector(x, y, evt);
|
|
216
|
+ }
|
217
|
217
|
}
|
218
|
|
- }
|
219
|
218
|
|
220
|
|
- function releaseSelector(x ,y , evt) {
|
221
|
|
- if (selectorState == selectorStates.selecting) {
|
222
|
|
- selected_els = calculateSelection();
|
223
|
|
- if (selected_els.length == 0) {
|
224
|
|
- selectionRect.style.display = "none";
|
225
|
|
- }
|
|
219
|
+ function releaseSelector(x, y, evt) {
|
|
220
|
+ if (selectorState == selectorStates.selecting) {
|
|
221
|
+ selected_els = calculateSelection();
|
|
222
|
+ if (selected_els.length == 0) {
|
|
223
|
+ selectionRect.style.display = "none";
|
|
224
|
+ }
|
|
225
|
+ }
|
|
226
|
+ translation_elements = [];
|
|
227
|
+ selectorState = selectorStates.pointing;
|
226
|
228
|
}
|
227
|
|
- translation_elements = [];
|
228
|
|
- selectorState = selectorStates.pointing;
|
229
|
|
- }
|
230
|
229
|
|
231
|
|
- function moveSelector(x, y, evt) {
|
232
|
|
- if (selectorState == selectorStates.selecting) {
|
233
|
|
- updateRect(x,y, selectionRect);
|
234
|
|
- } else if (selectorState == selectorStates.moving) {
|
235
|
|
- moveSelection(x,y, selectionRect);
|
|
230
|
+ function moveSelector(x, y, evt) {
|
|
231
|
+ if (selectorState == selectorStates.selecting) {
|
|
232
|
+ updateRect(x, y, selectionRect);
|
|
233
|
+ } else if (selectorState == selectorStates.moving) {
|
|
234
|
+ moveSelection(x, y, selectionRect);
|
|
235
|
+ }
|
236
|
236
|
}
|
237
|
|
- }
|
238
|
237
|
|
239
|
238
|
function startHand(x, y, evt, isTouchEvent) {
|
240
|
239
|
if (!isTouchEvent) {
|
|
@@ -263,7 +262,7 @@
|
263
|
262
|
|
264
|
263
|
function release(x, y, evt, isTouchEvent) {
|
265
|
264
|
move(x, y, evt, isTouchEvent);
|
266
|
|
- if (handTool.secondary.active) releaseSelector(x, y, evt, isTouchEvent);
|
|
265
|
+ if (handTool.secondary.active) releaseSelector(x, y, evt, isTouchEvent);
|
267
|
266
|
selected = null;
|
268
|
267
|
}
|
269
|
268
|
|