source: main/trunk/greenstone3/web/interfaces/default/js/map-scripts-editor.js@ 32769

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

Map editor history changed into an object prototype (class).

File size: 19.2 KB
Line 
1var debug = false;
2var shiftKeyPressed = false;
3var beingDragged = false;
4var resizeEntry = false;
5var allowDeselect = true;
6var colors = ['#1E90FF', '#FF1493', '#4B0082', '#32CD32', '#FF8C00', '#000000'];
7var selectedColor;
8var colorButtons = {};
9var thicknessValue = 1;
10var opacityValue = 0.4;
11var draggableState = true
12var overlays = [];
13var entryType = [];
14var selectedShapes = [];
15var listenersArray = [];
16var mapsArray = [];
17var controlsId = null;
18var drawingManager;
19var selectedShape;
20var map = null;
21var dragS, dragN;
22var dsNorth, dsSouth, dsEast, dsWest;
23//var gaj, gal, maj, mal;
24var counter = 0;
25var branchNum = 1;
26var mouseState = "up";
27var thicknessRangeListener = thicknessValue;
28var resizable = false;
29var dontResize = false;
30
31var mapEditorHistory = new MapEditorHistory();
32
33var polyOptions = {
34 fillColor: '#CA4A2F',
35 strokeWeight: thicknessValue,
36 fillOpacity: opacityValue,
37 editable: true,
38 draggable: draggableState,
39 geodesic: false
40};
41
42function MapEditor() {
43 this.shiftKeyPressed = false;
44 this.beingDragged = false;
45 this.resizeEntry = false;
46 this.allowDeselect = true;
47 this.colors = ['#1E90FF', '#FF1493', '#4B0082', '#32CD32', '#FF8C00', '#000000'];
48 this.selectedColor;
49 this.colorButtons = {};
50 this.thicknessValue = 1;
51 this.opacityValue = 0.4;
52 this.draggableState = true
53 this.overlays = [];
54 this.entryType = [];
55 this.selectedShapes = [];
56 this.listenersArray = [];
57 this.mapsArray = [];
58 this.controlsId = null;
59 this.drawingManager;
60 this.selectedShape;
61 this.map = null;
62 this.dragS, dragN;
63 this.dsNorth, dsSouth, dsEast, dsWest;
64 // gaj, gal, maj, mal;
65 this.counter = 0;
66 this.branchNum = 1;
67 this.mouseState = "up";
68 this.thicknessRangeListener = thicknessValue;
69 this.resizable = false;
70 this.dontResize = false;
71
72 this.mapEditorHistory = new MapEditorHistory();
73
74 this.polyOptions = {
75 fillColor: '#CA4A2F',
76 strokeWeight: thicknessValue,
77 fillOpacity: opacityValue,
78 editable: true,
79 draggable: this.draggableState,
80 geodesic: false
81};
82}
83
84//MapEditor.prototype.initMapEditorControls = function(id) {
85//};
86
87
88function initMapEditorControls(id) {
89 console.log(id);
90 //change draggable
91 var draggableCB = document.querySelector("input[name=draggableCB]");
92
93 draggableCB.addEventListener('change', function () {
94 if (this.checked) {
95 draggableState = false;
96 for (var i = 0; i < overlays.length; i++) {
97 overlays[i].draggable = draggableState;
98 polyOptions.draggable = draggableState;
99 }
100 } else {
101 draggableState = true;
102 for (var i = 0; i < overlays.length; i++) {
103 overlays[i].draggable = draggableState;
104 polyOptions.draggable = draggableState;
105 }
106 }
107 });
108
109 //Update thickness
110 var thicknessSlider = document.getElementById("thicknessRange" +"-"+ id);
111 var thicknessSliderOutput = document.getElementById("thicknessRangeVal" +"-"+ id);
112 thicknessSliderOutput.innerHTML = thicknessSlider.value / 20;
113
114 thicknessSlider.oninput = function () {
115 shapeSpecsChangeMD();
116 thicknessSliderOutput.innerHTML = this.value / 20;
117 thicknessValue = this.value / 20;
118 polyOptions.strokeWeight = thicknessValue;
119 setSelectedThickness(thicknessValue);
120
121 }
122 //Update opacity
123 var opacitySlider = document.getElementById("colourOpacity" +"-"+ id);
124 var opacitySliderOutput = document.getElementById("opacityRangeVal" +"-"+ id);
125 opacitySliderOutput.innerHTML = Math.round(opacitySlider.value) /100;
126
127 opacitySlider.oninput = function () {
128 shapeSpecsChangeMD();
129 opacitySliderOutput.innerHTML = "% " + this.value;
130 opacityValue = this.value / 100;
131 polyOptions.fillOpacity = opacityValue;
132 setSelectedOpacity(opacityValue);
133 }
134
135 document.getElementById("color-palette1" +"-"+ id).addEventListener("mousedown", shapeSpecsChangeMD);
136 document.getElementById("thicknessRange" +"-"+ id).addEventListener("mouseup", shapeSpecsChangeMU);
137 document.getElementById("colourOpacity" +"-"+ id).addEventListener("mouseup", shapeSpecsChangeMU);
138 document.onmousemove = mouseMove;
139 document.onmousedown = mouseDown;
140 document.onmouseup = mouseUp;
141}
142
143
144function settingThePath() {
145 listenersArray = []
146 counter = 0;
147 branchNum = 1;
148
149 for (var i = 0; i < selectedShapes.length * 2; i++) {
150 for (var j = 1; j < 5; j++) {
151 var path = "//*[@id='map']/div/div/div[1]/div[3]/div/div[3]/div[" + branchNum + "]/div[" + j + "]/div";
152 listenersArray[counter] = getElementByXpath(path);
153 if (listenersArray[counter] !== undefined && listenersArray[counter] !== null) {
154 listenersArray[counter].addEventListener("mousemove", function () {
155 resizable = true;
156 shapeResize();
157 });
158 listenersArray[counter].addEventListener("mouseout", function () {
159 if (mouseDown) {
160 resizable = true;
161 shapeResize();
162 }
163 });
164 }
165 counter++;
166 }
167 branchNum++;
168 }
169}
170
171
172
173function shapeResize() {
174 if (mouseState == "down") {
175 if (selectedShapes.length > 0) {
176 if (resizable) {
177 if(dontResize == false){
178 mapEditorHistory.historyOverlayPush();
179 }
180
181 }
182 }
183 }
184}
185
186function shapeSpecsChangeMD() {
187
188 if (selectedShapes.length > 0) {
189 mapEditorHistory.historyOverlayPush();
190 }
191}
192
193function shapeSpecsChangeMU() {
194 if (selectedShapes.length > 0) {
195 mapEditorHistory.presentOverlayPush ();
196 }
197}
198
199function makeColorButton(color) {
200 var button = document.createElement('span');
201 button.className = 'color-buttons1';
202 button.style.backgroundColor = color;
203 google.maps.event.addDomListener(button, 'click', function () {
204 selectColor(color);
205 setSelectedShapeColor(color);
206 shapeSpecsChangeMU();
207 });
208 return button;
209}
210function buildColorPalette(id) {
211 console.log("colour palette build");
212 var colorPalette = document.getElementById("color-palette1" +"-"+ id);
213 for (var i = 0; i < colors.length; ++i) {
214 var currColor = colors[i];
215 var colorButton = makeColorButton(currColor);
216 colorPalette.appendChild(colorButton);
217 colorButtons[currColor] = colorButton;
218 }
219 selectColor(colors[0]);
220};
221function selectColor(color) {
222 selectedColor = color;
223 for (var i = 0; i < colors.length; ++i) {
224 var currColor = colors[i];
225 colorButtons[currColor].style.border = currColor == color ? '2px solid #789' : '2px solid #fff';
226 }
227
228 // Retrieves the current options from the drawing manager and replaces the
229 // stroke or fill color as appropriate.
230 var polylineOptions = drawingManager.get('polylineOptions');
231 polylineOptions.strokeColor = color;
232 drawingManager.set('polylineOptions', polylineOptions);
233
234 var rectangleOptions = drawingManager.get('rectangleOptions');
235 rectangleOptions.fillColor = color;
236 drawingManager.set('rectangleOptions', rectangleOptions);
237
238 var circleOptions = drawingManager.get('circleOptions');
239 circleOptions.fillColor = color;
240 drawingManager.set('circleOptions', circleOptions);
241
242 var polygonOptions = drawingManager.get('polygonOptions');
243 polygonOptions.fillColor = color;
244 drawingManager.set('polygonOptions', polygonOptions);
245}
246
247function initMapEditor(id) {
248 var that = this;
249
250 map = new google.maps.Map(document.getElementById("map-" + id), {
251 center: {
252 lat: -37.7891,
253 lng: 175.3180
254 },
255 zoom: 14,
256 mapId: id,
257 });
258 mapsArray.push(map);
259 console.log(map);
260 // Add a style-selector control to the map.
261 var styleControl = document.getElementById('style-selector-control' +"-"+ id);
262 map.controls[google.maps.ControlPosition.TOP_LEFT].push(styleControl);
263
264 // Set the map's style to the initial value of the selector.
265 var styleSelector = document.getElementById('style-selector' +"-"+ id);
266 console.log(styleSelector);
267 //map = google.maps.Map(document.getElementById('map' +"-"+ id));
268 console.log(map);
269 map.setOptions({
270 styles: styles[styleSelector.value]
271
272 });
273
274 // Apply new JSON when the user selects a different style.
275 styleSelector.addEventListener('change', function () {
276 console.log(id);
277 mapsArray.indexOf(map).setOptions({
278 styles: styles[styleSelector.value]
279 });
280 });
281
282 drawingManager = new google.maps.drawing.DrawingManager({
283 drawingMode: google.maps.drawing.OverlayType.RECTANGLE,
284 drawingControl: true,
285 drawingControlOptions: {
286 position: google.maps.ControlPosition.TOP_CENTER,
287 drawingModes: ['marker', 'circle', 'polygon', 'polyline', 'rectangle']
288 },
289 markerOptions: {
290 draggable: draggableState
291 },
292 circleOptions: polyOptions,
293 polylineOptions: polyOptions,
294 polygonOptions: polyOptions,
295 rectangleOptions: polyOptions,
296 });
297
298 drawingManager.setMap(map);
299
300 google.maps.event.addListener(drawingManager, "drawingmode_changed", function () {
301 if(shiftKeyPressed != true && drawingManager.drawingMode !== null){
302 deselectAll();
303 }
304 settingThePath();
305
306 })
307
308 // store reference to added overlay
309 google.maps.event.addListener(drawingManager, 'overlaycomplete', function (e) {
310 allowDeselect = true;
311 mapEditorHistory.historyOverlayPush();
312 overlays.push(e.overlay); // store reference to added overlay
313 var newShape = e.overlay;
314 newShape.type = e.type;
315 mapEditorHistory.presentOverlayPush();
316
317 if (e.type !== google.maps.drawing.OverlayType.MARKER) {
318 addShapeListeners(newShape, e);
319 setSelection(newShape, e);
320 } else {
321
322 addMarkerListeners(newShape, e);
323 setSelection(newShape, e);
324 }
325 });
326
327 //Clears selection if clicked on the map when shift is not presseed
328 google.maps.event.addListener(map, 'click', function (e) {
329 var c = document.body.childNodes;
330 if (e.target && e.target.matches("a.classA")) {
331 console.log("Anchor element clicked!");
332 }
333 if (shiftKeyPressed == false) {
334 clearSelection();
335 selectedShape = null;
336 }
337 });
338
339 google.maps.event.addListener(map, 'mousedown', function (e) {
340 dontResize = true;
341 });
342
343 google.maps.event.addListener(map, 'mouseup', function (e) {
344 dontResize = false;
345 });
346
347 //Keyboard shortcuts
348 document.addEventListener('keydown', function () {
349 if (event.code == 'KeyY' && (event.ctrlKey || event.metaKey) || (event.code == 'KeyZ' && event.code == 'ShiftLeft' && (event.ctrlKey || event.metaKey))) {
350 mapEditorHistory.redo();
351 }
352 if (event.code == 'KeyZ' && (event.ctrlKey || event.metaKey)) {
353 if (shiftKeyPressed == false) {
354 //undo();
355 mapEditorHistory.undo();
356 //mapEditorHistory.undo(overlays, draggableState); // ***** when we only have MapEditorHistory as a class
357 //that.mapEditorHistory.undo(that.overlays); // ***** when we have both MapEditorHistory and MapEditor as classes
358
359 }
360 }
361 if (event.code == 'KeyA' && (event.ctrlKey || event.metaKey)) {
362 event.preventDefault();
363 drawingManager.setDrawingMode(null);
364 selectAll();
365
366 }
367 if (event.code == 'KeyD' && (event.ctrlKey || event.metaKey)) {
368 event.preventDefault();
369 deselectAll();
370 }
371 if (event.code == 'Digit0' || event.code == 'Numpad0' || event.code == 'Backquote') {
372
373 drawingManager.setDrawingMode(null);
374 } else if (event.code == 'Digit1') {
375 drawingManager.setDrawingMode('marker');
376 } else if (event.code == 'Digit2') {
377 drawingManager.setDrawingMode('circle');
378 } else if (event.code == 'Digit3') {
379 drawingManager.setDrawingMode('polygon');
380 } else if (event.code == 'Digit4') {
381 drawingManager.setDrawingMode('polyline');
382 } else if (event.code == 'Digit5') {
383 drawingManager.setDrawingMode('rectangle');
384 } else if (event.code == 'KeyQ') {
385 printHistory();
386 }
387 // console.log(event.code);
388 });
389
390 //Sets shift as pressed
391 document.addEventListener('keydown', function () {
392 if (event.code == 'ShiftLeft' || event.code == 'ShiftRight') {
393 shiftKeyPressed = true;
394
395 }
396
397 });
398
399 //Sets shift as unpressed
400 document.addEventListener('keyup', function () {
401 if (event.code == 'ShiftLeft' || event.code == 'ShiftRight') {
402 shiftKeyPressed = false;
403 }
404
405 });
406
407 buildColorPalette(id);
408}
409
410//Deletes a vertex if clicked on it
411function vertexAndPolyDel(e, newShape) {
412 var vertex = e.vertex;
413 if (e.vertex !== undefined) {
414 if (newShape.type === google.maps.drawing.OverlayType.POLYGON) {
415 var path = newShape.getPaths().getAt(e.path);
416 path.removeAt(e.vertex);
417 if (path.length < 3) {
418 newShape.setMap(null);
419 }
420 }
421 if (newShape.type === google.maps.drawing.OverlayType.POLYLINE) {
422 var path = newShape.getPath();
423 path.removeAt(e.vertex);
424 if (path.length < 2) {
425 newShape.setMap(null);
426 }
427 }
428 }
429}
430
431function addMarkerListeners(newShape, e) {
432 //cLICK EVENT IF A MARKER IS CREATED
433 google.maps.event.addListener(newShape, 'click', function (e) {
434 setSelection(newShape, e);
435 });
436
437 google.maps.event.addListener(newShape, 'dragstart', function (e) {
438 beingDragged = true;
439 mapEditorHistory.historyOverlayPush();
440
441 });
442
443 google.maps.event.addListener(newShape, 'dragend', function () {
444 beingDragged = false;
445 mapEditorHistory.presentOverlayPush ();
446 allowDeselect = false;
447 });
448}
449
450function addShapeListeners(newShape, e) {
451 // Add an event listener that selects the newly-drawn shape when the user
452 // mouses down on it.
453 google.maps.event.addListener(newShape, 'click', function (e) {
454
455 vertexAndPolyDel(e, newShape);
456
457 });
458
459 google.maps.event.addListener(newShape, 'dragstart', function (e) {
460 allowDeselect = false;
461 mapEditorHistory.historyOverlayPush();
462 });
463
464
465
466 google.maps.event.addListener(newShape, 'dragend', function () {
467 beingDragged = false;
468 mapEditorHistory.presentOverlayPush ();
469 settingThePath();
470
471 allowDeselect = false;
472 setSelection(newShape, e);
473 });
474
475 //Store information after the event ends
476 google.maps.event.addListener(newShape, 'bounds_changed', function (e) {
477 if (beingDragged == false) {
478 mapEditorHistory.presentOverlayPush ();
479 }
480 });
481
482 //Add an event listener to select a shape if the mouse hovers over it
483 google.maps.event.addListener(newShape, 'mousedown', function (e) {
484 if (e.target && e.target.matches("a.classA")) {
485 console.log("Anchor element clicked!");
486 }
487 if (e.vertex !== undefined || e.edge !== undefined) {
488 mapEditorHistory.historyOverlayPush()
489 }
490 if (drawingManager.drawingMode == null) {
491 setSelection(newShape, e);
492 }
493 });
494
495 google.maps.event.addListener(newShape, 'mouseup', function (e) {
496 if (e.vertex !== undefined || e.edge !== undefined) {
497 mapEditorHistory.presentOverlayPush ()
498 } else {
499 //setSelection(newShape, e);
500 }
501
502 });
503}
504function clearSelection() {
505 if (selectedShape) {
506 if (selectedShape.type !== 'marker') {
507 selectedShape.setEditable(false);
508 if (shiftKeyPressed == false) {
509 for (var i = 0; i < selectedShapes.length; i++) {
510 selectedShapes[i].setEditable(false);
511 }
512 selectedShapes = [];
513 }
514 }
515 selectedShape = null;
516 }
517}
518
519//Set selection for the selected overlay
520function setSelection(shape, e) {
521 if (shape.type !== 'marker') {
522 if (shiftKeyPressed == false) {
523 if(e !== null) {
524 if (e.vertex == undefined) {
525 if (e.edge == undefined) {
526 clearSelection();
527 shape.setEditable(true);
528 }
529 }
530 }
531 }
532 if (selectedShapes.includes(shape)) {
533 if(e !== null){
534 if (e.vertex == undefined) {
535 if (e.edge == undefined) {
536 allowDeselect = true;
537 removeFromSelectedShapes(shape);
538 }
539 }
540 }
541 } else {
542 allowDeselect = false;
543 shape.setEditable(true);
544 selectedShapes.push(shape);
545 }
546
547 //Send the values to be updated
548 var thi = shape.strokeWeight;
549 var opa = shape.fillOpacity;
550 var fCol = shape.fillColor;
551 var sCol = shape.strokeColor;
552 //updateMenuValues(thi, opa, fCol, sCol);
553
554 } else if (shape.type == 'marker') {
555 clearSelection();
556 }
557 selectedShape = shape;
558 settingThePath();
559}
560
561function removeFromSelectedShapes(shape) {
562 if (selectedShapes.includes(shape)) {
563 if (allowDeselect) {
564 const index = selectedShapes.indexOf(shape);
565 selectedShapes.splice(index, 1);
566 shape.setEditable(false);
567 }
568 allowDeselect = true;
569 }
570}
571
572//Set selected thickness
573function setSelectedThickness(sWeight) {
574 if (selectedShapes.length > 0) {
575 //mapEditorHistory.historyOverlayPush();
576 for (var i = 0; i < selectedShapes.length; i++) {
577 selectedShapes[i].set('strokeWeight', sWeight);
578 }
579 }
580}
581
582//Set selected opacity
583function setSelectedOpacity(fOpacity) {
584
585 if (selectedShapes.length > 0) {
586 for (var i = 0; i < selectedShapes.length; i++) {
587 selectedShapes[i].set('fillOpacity', fOpacity);
588 }
589 }
590}
591
592//set selected fill colour
593function setSelectedShapeColor(color) {
594 if (selectedShapes.length > 0) {
595 for (var i = 0; i < selectedShapes.length; i++) {
596 selectedShapes[i].set('fillColor', color);
597 selectedShapes[i].set('strokeColor', color);
598 }
599 }
600}
601function getElementByXpath(path) {
602 return document.evaluate(path, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
603}
604
605function updateMenuValues(thi, opa, fCol, sCol, id) {
606 //Update thickness slider and value on the settings menu
607 var thicknessSliderOutput = document.getElementById("thicknessRangeVal" +"-"+ id);
608 thicknessSliderOutput.innerHTML = thi;
609 document.getElementById("thicknessRange" +"-"+ id).value = thi * 20;
610
611 //Update the opacity slider and value on the settings menu
612 var opacitySliderOutput = document.getElementById("opacityRangeVal" +"-"+ id);
613 opacitySliderOutput.innerHTML = "% " + opa * 100;
614 document.getElementById("colourOpacity" +"-"+ id).value = opa * 100;
615
616 if (drawingManager.drawingMode == null) {
617 selectColor(fCol);
618 }
619}
620function selectAll() {
621 shiftKeyPressed = true;
622 var e = new Object();
623 e.vertex = undefined;
624 selectedShapes = [];
625 for (var i = 0; i < overlays.length; i++) {
626 setSelection(overlays[i], e);
627 }
628 shiftKeyPressed = false;
629}
630
631function deselectAll() {
632 for (var i = 0; i < selectedShapes.length; i++) {
633 selectedShapes[i].setEditable(false);
634 }
635 selectedShapes = [];
636}
637
638function printHistory() {
639 console.log("prev", mapEditorHistory.prevOverlays);
640 console.log("present ", mapEditorHistory.presentOverlays);
641 console.log("undone ", mapEditorHistory.undoneOverlays);
642 console.log(mouseState);
643}
644
645function mouseMove(ev) {
646
647 //How can I know the state of mouse from here
648 if (mouseState == 'down') {
649 //console.log('mouse down state')
650 }
651
652 if (mouseState == 'up') {
653 //console.log('mouse up state')
654 }
655}
656
657function mouseDown(ev) {
658 mouseState = "down";
659 // console.log('Down State you can now start dragging');
660 //do not write any code here in this function
661}
662
663function mouseUp(ev) {
664 mouseState = "up";
665 // console.log('up state you cannot drag now because you are not holding your mouse')
666 //do not write any code here in this function
667}
668
669function deleteSelectedShape() {
670 //console.log("this fires");
671 mapEditorHistory.historyOverlayPush();
672 for (var i = 0; i < selectedShapes.length; i++) {
673 selectedShapes[i].setMap(null);
674
675 if (overlays.includes(selectedShapes[i])) {
676 const index = overlays.indexOf(selectedShapes[i]);
677 overlays.splice(index, 1);
678 selectedShapes[i].setEditable(false);
679 }
680 }
681 selectedShapes = [];
682 //console.log("this fires");
683 mapEditorHistory.presentOverlayPush ();
684}
685
686function deleteAllShape(nId) {
687 console.log(nId);
688 //console.log("this fires");
689 mapEditorHistory.historyOverlayPush();
690 for (var i = 0; i < overlays.length; i++) {
691 overlays[i].setMap(null);
692 }
693 overlays = [];
694 //console.log("this fires");
695 mapEditorHistory.presentOverlayPush ();
696}
Note: See TracBrowser for help on using the repository browser.