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

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

Map editor and history + map themes files

File size: 18.8 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 historyOverlayPush();
179 }
180
181 }
182 }
183 }
184}
185
186function shapeSpecsChangeMD() {
187
188 if (selectedShapes.length > 0) {
189 historyOverlayPush();
190 }
191}
192
193function shapeSpecsChangeMU() {
194 if (selectedShapes.length > 0) {
195 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 historyOverlayPush();
312 overlays.push(e.overlay); // store reference to added overlay
313 var newShape = e.overlay;
314 newShape.type = e.type;
315 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 redo();
351 }
352 if (event.code == 'KeyZ' && (event.ctrlKey || event.metaKey)) {
353 if (shiftKeyPressed == false) {
354 undo();
355 mapEditorHistory.undo(overlays); // ***** when we only have MapEditorHistory as a class
356 //that.mapEditorHistory.undo(that.overlays); // ***** when we have both MapEditorHistory and MapEditor as classes
357
358 }
359 }
360 if (event.code == 'KeyA' && (event.ctrlKey || event.metaKey)) {
361 event.preventDefault();
362 drawingManager.setDrawingMode(null);
363 selectAll();
364
365 }
366 if (event.code == 'KeyD' && (event.ctrlKey || event.metaKey)) {
367 event.preventDefault();
368 deselectAll();
369 }
370 if (event.code == 'Digit0' || event.code == 'Numpad0' || event.code == 'Backquote') {
371
372 drawingManager.setDrawingMode(null);
373 } else if (event.code == 'Digit1') {
374 drawingManager.setDrawingMode('marker');
375 } else if (event.code == 'Digit2') {
376 drawingManager.setDrawingMode('circle');
377 } else if (event.code == 'Digit3') {
378 drawingManager.setDrawingMode('polygon');
379 } else if (event.code == 'Digit4') {
380 drawingManager.setDrawingMode('polyline');
381 } else if (event.code == 'Digit5') {
382 drawingManager.setDrawingMode('rectangle');
383 } else if (event.code == 'KeyQ') {
384 printHistory();
385 }
386 // console.log(event.code);
387 });
388
389 //Sets shift as pressed
390 document.addEventListener('keydown', function () {
391 if (event.code == 'ShiftLeft' || event.code == 'ShiftRight') {
392 shiftKeyPressed = true;
393
394 }
395
396 });
397
398 //Sets shift as unpressed
399 document.addEventListener('keyup', function () {
400 if (event.code == 'ShiftLeft' || event.code == 'ShiftRight') {
401 shiftKeyPressed = false;
402 }
403
404 });
405
406 buildColorPalette(id);
407}
408
409//Deletes a vertex if clicked on it
410function vertexAndPolyDel(e, newShape) {
411 var vertex = e.vertex;
412 if (e.vertex !== undefined) {
413 if (newShape.type === google.maps.drawing.OverlayType.POLYGON) {
414 var path = newShape.getPaths().getAt(e.path);
415 path.removeAt(e.vertex);
416 if (path.length < 3) {
417 newShape.setMap(null);
418 }
419 }
420 if (newShape.type === google.maps.drawing.OverlayType.POLYLINE) {
421 var path = newShape.getPath();
422 path.removeAt(e.vertex);
423 if (path.length < 2) {
424 newShape.setMap(null);
425 }
426 }
427 }
428}
429
430function addMarkerListeners(newShape, e) {
431 //cLICK EVENT IF A MARKER IS CREATED
432 google.maps.event.addListener(newShape, 'click', function (e) {
433 setSelection(newShape, e);
434 });
435
436 google.maps.event.addListener(newShape, 'dragstart', function (e) {
437 beingDragged = true;
438 historyOverlayPush();
439
440 });
441
442 google.maps.event.addListener(newShape, 'dragend', function () {
443 beingDragged = false;
444 presentOverlayPush();
445 allowDeselect = false;
446 });
447}
448
449function addShapeListeners(newShape, e) {
450 // Add an event listener that selects the newly-drawn shape when the user
451 // mouses down on it.
452 google.maps.event.addListener(newShape, 'click', function (e) {
453
454 vertexAndPolyDel(e, newShape);
455
456 });
457
458 google.maps.event.addListener(newShape, 'dragstart', function (e) {
459 allowDeselect = false;
460 historyOverlayPush();
461 });
462
463
464
465 google.maps.event.addListener(newShape, 'dragend', function () {
466 beingDragged = false;
467 presentOverlayPush();
468 settingThePath();
469
470 allowDeselect = false;
471 setSelection(newShape, e);
472 });
473
474 //Store information after the event ends
475 google.maps.event.addListener(newShape, 'bounds_changed', function (e) {
476 if (beingDragged == false) {
477 presentOverlayPush();
478 }
479 });
480
481 //Add an event listener to select a shape if the mouse hovers over it
482 google.maps.event.addListener(newShape, 'mousedown', function (e) {
483 if (e.target && e.target.matches("a.classA")) {
484 console.log("Anchor element clicked!");
485 }
486 if (e.vertex !== undefined || e.edge !== undefined) {
487 historyOverlayPush()
488 }
489 if (drawingManager.drawingMode == null) {
490 setSelection(newShape, e);
491 }
492 });
493
494 google.maps.event.addListener(newShape, 'mouseup', function (e) {
495 if (e.vertex !== undefined || e.edge !== undefined) {
496 presentOverlayPush()
497 } else {
498 //setSelection(newShape, e);
499 }
500
501 });
502}
503function clearSelection() {
504 if (selectedShape) {
505 if (selectedShape.type !== 'marker') {
506 selectedShape.setEditable(false);
507 if (shiftKeyPressed == false) {
508 for (var i = 0; i < selectedShapes.length; i++) {
509 selectedShapes[i].setEditable(false);
510 }
511 selectedShapes = [];
512 }
513 }
514 selectedShape = null;
515 }
516}
517
518//Set selection for the selected overlay
519function setSelection(shape, e) {
520 if (shape.type !== 'marker') {
521 if (shiftKeyPressed == false) {
522 if(e !== null) {
523 if (e.vertex == undefined) {
524 if (e.edge == undefined) {
525 clearSelection();
526 shape.setEditable(true);
527 }
528 }
529 }
530 }
531 if (selectedShapes.includes(shape)) {
532 if(e !== null){
533 if (e.vertex == undefined) {
534 if (e.edge == undefined) {
535 allowDeselect = true;
536 removeFromSelectedShapes(shape);
537 }
538 }
539 }
540 } else {
541 allowDeselect = false;
542 shape.setEditable(true);
543 selectedShapes.push(shape);
544 }
545
546 //Send the values to be updated
547 var thi = shape.strokeWeight;
548 var opa = shape.fillOpacity;
549 var fCol = shape.fillColor;
550 var sCol = shape.strokeColor;
551 //updateMenuValues(thi, opa, fCol, sCol);
552
553 } else if (shape.type == 'marker') {
554 clearSelection();
555 }
556 selectedShape = shape;
557 settingThePath();
558}
559
560function removeFromSelectedShapes(shape) {
561 if (selectedShapes.includes(shape)) {
562 if (allowDeselect) {
563 const index = selectedShapes.indexOf(shape);
564 selectedShapes.splice(index, 1);
565 shape.setEditable(false);
566 }
567 allowDeselect = true;
568 }
569}
570
571//Set selected thickness
572function setSelectedThickness(sWeight) {
573 if (selectedShapes.length > 0) {
574 //historyOverlayPush();
575 for (var i = 0; i < selectedShapes.length; i++) {
576 selectedShapes[i].set('strokeWeight', sWeight);
577 }
578 }
579}
580
581//Set selected opacity
582function setSelectedOpacity(fOpacity) {
583
584 if (selectedShapes.length > 0) {
585 for (var i = 0; i < selectedShapes.length; i++) {
586 selectedShapes[i].set('fillOpacity', fOpacity);
587 }
588 }
589}
590
591//set selected fill colour
592function setSelectedShapeColor(color) {
593 if (selectedShapes.length > 0) {
594 for (var i = 0; i < selectedShapes.length; i++) {
595 selectedShapes[i].set('fillColor', color);
596 selectedShapes[i].set('strokeColor', color);
597 }
598 }
599}
600function getElementByXpath(path) {
601 return document.evaluate(path, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
602}
603
604function updateMenuValues(thi, opa, fCol, sCol, id) {
605 //Update thickness slider and value on the settings menu
606 var thicknessSliderOutput = document.getElementById("thicknessRangeVal" +"-"+ id);
607 thicknessSliderOutput.innerHTML = thi;
608 document.getElementById("thicknessRange" +"-"+ id).value = thi * 20;
609
610 //Update the opacity slider and value on the settings menu
611 var opacitySliderOutput = document.getElementById("opacityRangeVal" +"-"+ id);
612 opacitySliderOutput.innerHTML = "% " + opa * 100;
613 document.getElementById("colourOpacity" +"-"+ id).value = opa * 100;
614
615 if (drawingManager.drawingMode == null) {
616 selectColor(fCol);
617 }
618}
619function selectAll() {
620 shiftKeyPressed = true;
621 var e = new Object();
622 e.vertex = undefined;
623 selectedShapes = [];
624 for (var i = 0; i < overlays.length; i++) {
625 setSelection(overlays[i], e);
626 }
627 shiftKeyPressed = false;
628}
629
630function deselectAll() {
631 for (var i = 0; i < selectedShapes.length; i++) {
632 selectedShapes[i].setEditable(false);
633 }
634 selectedShapes = [];
635}
636
637function printHistory() {
638 console.log("prev", prevOverlays);
639 console.log("present ", presentOverlays);
640 console.log("undone ", undoneOverlays);
641 console.log(mouseState);
642}
643
644function mouseMove(ev) {
645
646 //How can I know the state of mouse from here
647 if (mouseState == 'down') {
648 //console.log('mouse down state')
649 }
650
651 if (mouseState == 'up') {
652 //console.log('mouse up state')
653 }
654}
655
656function mouseDown(ev) {
657 mouseState = "down";
658 // console.log('Down State you can now start dragging');
659 //do not write any code here in this function
660}
661
662function mouseUp(ev) {
663 mouseState = "up";
664 // console.log('up state you cannot drag now because you are not holding your mouse')
665 //do not write any code here in this function
666}
667
668function deleteSelectedShape() {
669 //console.log("this fires");
670 historyOverlayPush();
671 for (var i = 0; i < selectedShapes.length; i++) {
672 selectedShapes[i].setMap(null);
673
674 if (overlays.includes(selectedShapes[i])) {
675 const index = overlays.indexOf(selectedShapes[i]);
676 overlays.splice(index, 1);
677 selectedShapes[i].setEditable(false);
678 }
679 }
680 selectedShapes = [];
681 //console.log("this fires");
682 presentOverlayPush();
683}
684
685function deleteAllShape(nId) {
686 console.log(nId);
687 //console.log("this fires");
688 historyOverlayPush();
689 for (var i = 0; i < overlays.length; i++) {
690 overlays[i].setMap(null);
691 }
692 overlays = [];
693 //console.log("this fires");
694 presentOverlayPush();
695}
Note: See TracBrowser for help on using the repository browser.