source: gs3-extensions/map-editor/DrawingManager/index.js@ 32723

Last change on this file since 32723 was 32723, checked in by ak19, 5 years ago

Complete redo and undo and fixed marker drawing bug

File size: 13.9 KB
Line 
1var debug = false;
2var shiftKeyPressed = false;
3var beingDragged = false;
4var resizeEntry = false;
5var allowDeselect = false;
6var colors = ['#1E90FF', '#FF1493', '#4B0082', '#32CD32', '#FF8C00', '#000000'];
7var selectedColor;
8var colorButtons = {};
9var thicknessValue = 1;
10var opacityValue = 0.4;
11var overlays = [];
12var drawingManager;
13var selectedShape;
14var selectedShapes = [];
15var map = null;
16var faj, fal, maj, mal;
17var polyOptions = {fillColor: '#CA4A2F', strokeWeight: thicknessValue, fillOpacity: opacityValue, editable: true, draggable: true, geodesic: false};
18
19
20$(document).ready(function() {
21 //Update thickness
22 var thicknessSlider = document.getElementById("thicknessRange");
23 var thicknessSliderOutput = document.getElementById("thicknessRangeVal");
24 thicknessSliderOutput.innerHTML = thicknessSlider.value / 20;
25
26 thicknessSlider.oninput = function () {
27 thicknessSliderOutput.innerHTML = this.value / 20;
28 thicknessValue = this.value / 20;
29 polyOptions.strokeWeight = thicknessValue;
30 setSelectedThickness(thicknessValue);
31 }
32 //Update opacity
33 var opacitySlider = document.getElementById("colourOpacity");
34 var opacitySliderOutput = document.getElementById("opacityRangeVal");
35 opacitySliderOutput.innerHTML = "% " + Math.round(opacitySlider.value);
36
37 opacitySlider.oninput = function () {
38 opacityValue = this.value / 100;
39 polyOptions.fillOpacity = opacityValue;
40 opacitySliderOutput = opacityValue;
41 opacityRangeVal.innerHTML = "% " + Math.round(opacitySliderOutput * 100);
42 setSelectedOpacity(opacityValue);
43 }
44
45 document.getElementById("thicknessRange").addEventListener("mousedown", shapeSpecsChangeMD);
46 document.getElementById("colourOpacity").addEventListener("mousedown", shapeSpecsChangeMD);
47 document.getElementById("color-palette1").addEventListener("mousedown", shapeSpecsChangeMD);
48
49 document.getElementById("thicknessRange").addEventListener("mouseup", shapeSpecsChangeMU);
50 document.getElementById("colourOpacity").addEventListener("mouseup", shapeSpecsChangeMU);
51});
52
53function shapeSpecsChangeMD() {
54 if (selectedShapes.length > 0) {
55 historyOverlayPush();
56 }
57}
58
59function shapeSpecsChangeMU() {
60 if (selectedShapes.length > 0) {
61 presentOverlayPush();
62 }
63}
64
65function makeColorButton(color) {
66 var button = document.createElement('span');
67 button.className = 'color-buttons1';
68 button.style.backgroundColor = color;
69 google.maps.event.addDomListener(button, 'click', function () {
70 selectColor(color);
71 setSelectedShapeColor(color);
72 shapeSpecsChangeMU();
73 });
74 return button;
75}
76function buildColorPalette() {
77 var colorPalette = document.getElementById('color-palette1');
78 for (var i = 0; i < colors.length; ++i) {
79 var currColor = colors[i];
80 var colorButton = makeColorButton(currColor);
81 colorPalette.appendChild(colorButton);
82 colorButtons[currColor] = colorButton;
83 }
84 selectColor(colors[0]);
85};
86function selectColor(color) {
87 selectedColor = color;
88 for (var i = 0; i < colors.length; ++i) {
89 var currColor = colors[i];
90 colorButtons[currColor].style.border = currColor == color ? '2px solid #789' : '2px solid #fff';
91 }
92
93 // Retrieves the current options from the drawing manager and replaces the
94 // stroke or fill color as appropriate.
95 var polylineOptions = drawingManager.get('polylineOptions');
96 polylineOptions.strokeColor = color;
97 drawingManager.set('polylineOptions', polylineOptions);
98
99 var rectangleOptions = drawingManager.get('rectangleOptions');
100 rectangleOptions.fillColor = color;
101 drawingManager.set('rectangleOptions', rectangleOptions);
102
103 var circleOptions = drawingManager.get('circleOptions');
104 circleOptions.fillColor = color;
105 drawingManager.set('circleOptions', circleOptions);
106
107 var polygonOptions = drawingManager.get('polygonOptions');
108 polygonOptions.fillColor = color;
109 drawingManager.set('polygonOptions', polygonOptions);
110}
111
112function initMap() {
113
114 map = new google.maps.Map(document.getElementById('map'), {
115 center: {lat: -34.397, lng: 150.644
116 },
117 zoom: 8,
118 });
119
120 drawingManager = new google.maps.drawing.DrawingManager({
121 drawingMode: google.maps.drawing.OverlayType.MARKER,
122 drawingControl: true,
123 drawingControlOptions: {
124 position: google.maps.ControlPosition.TOP_CENTER,
125 drawingModes: ['marker', 'circle', 'polygon', 'polyline', 'rectangle']
126 },
127 markerOptions: {
128 draggable: true
129 },
130 circleOptions: polyOptions,
131 polylineOptions: polyOptions,
132 polygonOptions: polyOptions,
133 rectangleOptions: polyOptions,
134 });
135
136 drawingManager.setMap(map);
137
138 //overlays.push(event.overlay); // store reference to added overlay
139 google.maps.event.addListener(drawingManager, 'overlaycomplete', function (e) {
140
141 historyOverlayPush();
142
143 overlays.push(e.overlay); // store reference to added overlay
144 var newShape = e.overlay;
145 newShape.type = e.type;
146
147 presentOverlayPush();
148
149 if (e.type !== google.maps.drawing.OverlayType.MARKER) {
150 addShapeListeners(newShape,e);
151 setSelection(newShape, e);
152 } else {
153
154 addMarkerListeners(newShape,e);
155 setSelection(newShape, e);
156 }
157 });
158
159 //Clears selection if clicked on the map when shift is not presseed
160 google.maps.event.addListener(map, 'click', function () {
161 if (shiftKeyPressed == false) {
162 clearSelection();
163 selectedShape = null;
164 }
165 });
166
167 //Keyboard shortcuts
168 document.addEventListener('keydown', function () {
169 if (event.code == 'KeyY' && (event.ctrlKey || event.metaKey) || (event.code == 'KeyZ' && event.code == 'ShiftLeft' && (event.ctrlKey || event.metaKey) )){
170 redo();
171
172 }
173 if (event.code == 'KeyZ' && (event.ctrlKey || event.metaKey)){
174 if(shiftKeyPressed == false) {
175 undo();
176 }
177 }
178 if (event.code == 'KeyA' && (event.ctrlKey || event.metaKey)){
179 event.preventDefault();
180 selectAll();
181 drawingManager.setDrawingMode(null);
182 }
183 if (event.code == 'KeyD' && (event.ctrlKey || event.metaKey)){
184 event.preventDefault();
185 deselectAll();
186 }
187 if (event.code == 'Digit0' || event.code == 'Numpad0' || event.code == 'Backquote') {
188 //clearSelection();
189 drawingManager.setDrawingMode(null);
190 } else if (event.code == 'Digit1') {
191 drawingManager.setDrawingMode('marker');
192 } else if (event.code == 'Digit2') {
193 drawingManager.setDrawingMode('circle');
194 } else if (event.code == 'Digit3') {
195 drawingManager.setDrawingMode('polygon');
196 } else if (event.code == 'Digit4') {
197 drawingManager.setDrawingMode('polyline');
198 } else if (event.code == 'Digit5') {
199 drawingManager.setDrawingMode('rectangle');
200 } else if (event.code == 'KeyQ') {
201 printHistory();
202 }
203// console.log(event.code);
204 });
205
206 //Sets shift as pressed
207 document.addEventListener('keydown', function () {
208 if (event.code == 'ShiftLeft' || event.code == 'ShiftRight') {
209 shiftKeyPressed = true;
210
211 }
212
213 });
214
215 //Sets shift as unpressed
216 document.addEventListener('keyup', function () {
217 if (event.code == 'ShiftLeft' || event.code == 'ShiftRight') {
218 shiftKeyPressed = false;
219 }
220
221 });
222
223 buildColorPalette();
224}
225
226 //Deletes a vertex if clicked on it
227 function vertexAndPolyDel(e, newShape) {
228 var vertex = e.vertex;
229 //console.log(e)
230 if (e.vertex !== undefined) {
231 historyOverlayPush();
232 if (newShape.type === google.maps.drawing.OverlayType.POLYGON) {
233 var path = newShape.getPaths().getAt(e.path);
234 path.removeAt(e.vertex);
235 if (path.length < 3) {
236 newShape.setMap(null);
237 }
238 }
239 if (newShape.type === google.maps.drawing.OverlayType.POLYLINE) {
240 var path = newShape.getPath();
241 path.removeAt(e.vertex);
242 if (path.length < 2) {
243 newShape.setMap(null);
244 }
245 }
246 presentOverlayPush();
247 }
248 }
249
250function addMarkerListeners(newShape,e)
251{
252 //cLICK EVENT IF A MARKER IS CREATED
253 google.maps.event.addListener(newShape, 'click', function (e) {
254 setSelection(newShape, e);
255 });
256
257 google.maps.event.addListener(newShape, 'dragstart', function (e) {
258
259 beingDragged = true;
260 historyOverlayPush();
261
262 });
263
264 google.maps.event.addListener(newShape, 'dragend', function () {
265 beingDragged = false;
266 presentOverlayPush();
267 allowDeselect = false;
268 });
269}
270function addShapeListeners(newShape,e)
271{
272 // Add an event listener that selects the newly-drawn shape when the user
273 // mouses down on it.
274 google.maps.event.addListener(newShape, 'click', function (e) {
275 vertexAndPolyDel(e, newShape);
276 });
277
278
279 google.maps.event.addListener(newShape, 'drag', function (e) {
280
281 //for(var i = 0; i < selectedShapes.length; i++) {
282 // if(newShape.type = 'rectangle') {
283 // var newBounds = {
284 // east: selectedShapes[i].getBounds().ea.l + (selectedShapes[i].getBounds().ea.l - faj),
285 // north: selectedShapes[i].getBounds().la.l + (selectedShapes[i].getBounds().la.l - fal),
286 // south: selectedShapes[i].getBounds().la.j + (selectedShapes[i].getBounds().la.j - maj),
287 // west: selectedShapes[i].getBounds().ea.j + (selectedShapes[i].getBounds().ea.j - mal)
288 // }
289 // selectedShapes[i].set
290 // } else {
291
292 // }
293 //
294 //}
295
296
297 });
298
299
300 google.maps.event.addListener(newShape, 'dragstart', function (e) {
301
302 beingDragged = true;
303 historyOverlayPush();
304
305 });
306
307 google.maps.event.addListener(newShape, 'dragend', function () {
308 beingDragged = false;
309 presentOverlayPush();
310 allowDeselect = false;
311 });
312
313 //Store information after the event ends
314 google.maps.event.addListener(newShape, 'bounds_changed', function (e) {
315 if (beingDragged == false){
316 resizeEntry = true;
317 presentOverlayPush();
318 resizeEntry = false;
319 }
320 });
321
322 //Add an event listener to select a shape if the mouse hovers over it
323 google.maps.event.addListener(newShape, 'mousedown', function (e) {
324 if (e.vertex !== undefined || e.edge !== undefined) {
325 historyOverlayPush()
326 }
327 if (drawingManager.drawingMode == null) {
328 setSelection(newShape, e);
329 }
330 });
331
332 google.maps.event.addListener(newShape, 'mouseup', function (e) {
333 if (e.vertex !== undefined || e.edge !== undefined) {
334 presentOverlayPush()
335 }
336 else{
337 removeFromSelectedShapes(newShape);
338 }
339 });
340}
341function clearSelection() {
342 if (selectedShape) {
343 if (selectedShape.type !== 'marker') {
344 selectedShape.setEditable(false);
345 if (shiftKeyPressed == false) {
346 for (var i = 0; i < selectedShapes.length; i++) {
347 selectedShapes[i].setEditable(false);
348 }
349 selectedShapes = [];
350 }
351 }
352 selectedShape = null;
353 }
354 }
355
356//Set selection for the selected overlay
357 function setSelection(shape, e) {
358 if (shape.type !== 'marker') {
359 if (shiftKeyPressed == false) {
360 if (e.vertex == undefined) {
361 if(e.edge == undefined) {
362 clearSelection();
363 shape.setEditable(true);
364 }
365 }
366 }
367 if (selectedShapes.includes(shape)) {
368 if(e.vertex == undefined ) {
369 if(e.edge == undefined) {
370 //removeFromSelectedShapes(shape);
371 }
372 }
373 } else {
374 shape.setEditable(true);
375 selectedShapes.push(shape);
376 }
377
378
379 //Send the values to be updated
380 var thi = shape.strokeWeight;
381 var opa = shape.fillOpacity;
382 var fCol = shape.fillColor;
383 var sCol = shape.strokeColor;
384 updateMenuValues(thi, opa, fCol, sCol);
385
386 } else if (shape.type == 'marker') {
387 clearSelection();
388 }
389 selectedShape = shape;
390 }
391
392
393function removeFromSelectedShapes(shape) {
394 if (selectedShapes.includes(shape)) {
395 if(allowDeselect) {
396 const index = selectedShapes.indexOf(shape);
397 selectedShapes.splice(index, 1);
398 shape.setEditable(false);
399 }
400 allowDeselect = false;
401 }
402
403
404}
405
406//Set selected thickness
407function setSelectedThickness(sWeight) {
408 if (selectedShapes.length > 0) {
409 //historyOverlayPush();
410 for (var i = 0; i < selectedShapes.length; i++) {
411 selectedShapes[i].set('strokeWeight', sWeight);
412 //console.log(selectedShapes.length);
413 }
414 }
415}
416
417//Set selected opacity
418function setSelectedOpacity(fOpacity) {
419
420 if (selectedShapes.length > 0) {
421 for (var i = 0; i < selectedShapes.length; i++) {
422 selectedShapes[i].set('fillOpacity', fOpacity);
423 }
424 }
425}
426
427//set selected fill colour
428function setSelectedShapeColor(color) {
429 if (selectedShapes.length > 0) {
430 for (var i = 0; i < selectedShapes.length; i++) {
431 selectedShapes[i].set('fillColor', color);
432 selectedShapes[i].set('strokeColor', color);
433 }
434 }
435}
436
437function updateMenuValues(thi, opa, fCol, sCol) {
438 //Update thickness slider and value on the settings menu
439 var thicknessSliderOutput = document.getElementById("thicknessRangeVal");
440 thicknessSliderOutput.innerHTML = thi;
441 document.getElementById("thicknessRange").value = thi * 20;
442
443 //Update the opacity slider and value on the settings menu
444 var opacitySliderOutput = document.getElementById("opacityRangeVal");
445 opacitySliderOutput.innerHTML = "% " + opa * 100;
446 document.getElementById("colourOpacity").value = opa * 100;
447
448 if (drawingManager.drawingMode == null) {
449 selectColor(fCol);
450 }
451}
452function selectAll(){
453 shiftKeyPressed = true;
454 var e = new Object();
455 e.vertex = undefined;
456 selectedShapes = [];
457 for(var i = 0; i< overlays.length; i++) {
458 setSelection(overlays[i], e);
459 }
460 shiftKeyPressed = false;
461}
462
463function deselectAll(){
464 for(var i = 0; i < selectedShapes.length; i++) {
465 selectedShapes[i].setEditable(false);
466 }
467 selectedShapes = [];
468}
469
470function printHistory() {
471 console.log("prev", prevOverlays);
472 console.log("present ", presentOverlays);
473 console.log("undone ", undoneOverlays);
474}
475
476function deleteSelectedShape() {
477 historyOverlayPush();
478 for (var i = 0; i < selectedShapes.length; i++) {
479 selectedShapes[i].setMap(null);
480
481 if (overlays.includes(selectedShapes[i])) {
482 const index = overlays.indexOf(selectedShapes[i]);
483 overlays.splice(index, 1);
484 selectedShapes[i].setEditable(false);
485 }
486 }
487 selectedShapes = [];
488 presentOverlayPush();
489}
490
491function deleteAllShape() {
492 historyOverlayPush();
493 for (var i = 0; i < overlays.length; i++) {
494 overlays[i].setMap(null);
495 }
496 overlays = [];
497 presentOverlayPush();
498}
499
Note: See TracBrowser for help on using the repository browser.