var debug = false; var shiftKeyPressed = false; var beingDragged = false; var resizeEntry = false; var allowDeselect = false; var colors = ['#1E90FF', '#FF1493', '#4B0082', '#32CD32', '#FF8C00', '#000000']; var selectedColor; var colorButtons = {}; var thicknessValue = 1; var opacityValue = 0.4; var overlays = []; var drawingManager; var selectedShape; var selectedShapes = []; var map = null; var faj, fal, maj, mal; var polyOptions = {fillColor: '#CA4A2F', strokeWeight: thicknessValue, fillOpacity: opacityValue, editable: true, draggable: true, geodesic: false}; $(document).ready(function() { //Update thickness var thicknessSlider = document.getElementById("thicknessRange"); var thicknessSliderOutput = document.getElementById("thicknessRangeVal"); thicknessSliderOutput.innerHTML = thicknessSlider.value / 20; thicknessSlider.oninput = function () { thicknessSliderOutput.innerHTML = this.value / 20; thicknessValue = this.value / 20; polyOptions.strokeWeight = thicknessValue; setSelectedThickness(thicknessValue); } //Update opacity var opacitySlider = document.getElementById("colourOpacity"); var opacitySliderOutput = document.getElementById("opacityRangeVal"); opacitySliderOutput.innerHTML = "% " + Math.round(opacitySlider.value); opacitySlider.oninput = function () { opacityValue = this.value / 100; polyOptions.fillOpacity = opacityValue; opacitySliderOutput = opacityValue; opacityRangeVal.innerHTML = "% " + Math.round(opacitySliderOutput * 100); setSelectedOpacity(opacityValue); } document.getElementById("thicknessRange").addEventListener("mousedown", shapeSpecsChangeMD); document.getElementById("colourOpacity").addEventListener("mousedown", shapeSpecsChangeMD); document.getElementById("color-palette1").addEventListener("mousedown", shapeSpecsChangeMD); document.getElementById("thicknessRange").addEventListener("mouseup", shapeSpecsChangeMU); document.getElementById("colourOpacity").addEventListener("mouseup", shapeSpecsChangeMU); }); function shapeSpecsChangeMD() { if (selectedShapes.length > 0) { historyOverlayPush(); } } function shapeSpecsChangeMU() { if (selectedShapes.length > 0) { presentOverlayPush(); } } function makeColorButton(color) { var button = document.createElement('span'); button.className = 'color-buttons1'; button.style.backgroundColor = color; google.maps.event.addDomListener(button, 'click', function () { selectColor(color); setSelectedShapeColor(color); shapeSpecsChangeMU(); }); return button; } function buildColorPalette() { var colorPalette = document.getElementById('color-palette1'); for (var i = 0; i < colors.length; ++i) { var currColor = colors[i]; var colorButton = makeColorButton(currColor); colorPalette.appendChild(colorButton); colorButtons[currColor] = colorButton; } selectColor(colors[0]); }; function selectColor(color) { selectedColor = color; for (var i = 0; i < colors.length; ++i) { var currColor = colors[i]; colorButtons[currColor].style.border = currColor == color ? '2px solid #789' : '2px solid #fff'; } // Retrieves the current options from the drawing manager and replaces the // stroke or fill color as appropriate. var polylineOptions = drawingManager.get('polylineOptions'); polylineOptions.strokeColor = color; drawingManager.set('polylineOptions', polylineOptions); var rectangleOptions = drawingManager.get('rectangleOptions'); rectangleOptions.fillColor = color; drawingManager.set('rectangleOptions', rectangleOptions); var circleOptions = drawingManager.get('circleOptions'); circleOptions.fillColor = color; drawingManager.set('circleOptions', circleOptions); var polygonOptions = drawingManager.get('polygonOptions'); polygonOptions.fillColor = color; drawingManager.set('polygonOptions', polygonOptions); } function initMap() { map = new google.maps.Map(document.getElementById('map'), { center: {lat: -34.397, lng: 150.644 }, zoom: 8, }); drawingManager = new google.maps.drawing.DrawingManager({ drawingMode: google.maps.drawing.OverlayType.MARKER, drawingControl: true, drawingControlOptions: { position: google.maps.ControlPosition.TOP_CENTER, drawingModes: ['marker', 'circle', 'polygon', 'polyline', 'rectangle'] }, markerOptions: { draggable: true }, circleOptions: polyOptions, polylineOptions: polyOptions, polygonOptions: polyOptions, rectangleOptions: polyOptions, }); drawingManager.setMap(map); //overlays.push(event.overlay); // store reference to added overlay google.maps.event.addListener(drawingManager, 'overlaycomplete', function (e) { historyOverlayPush(); overlays.push(e.overlay); // store reference to added overlay var newShape = e.overlay; newShape.type = e.type; presentOverlayPush(); if (e.type !== google.maps.drawing.OverlayType.MARKER) { addShapeListeners(newShape,e); setSelection(newShape, e); } else { addMarkerListeners(newShape,e); setSelection(newShape, e); } }); //Clears selection if clicked on the map when shift is not presseed google.maps.event.addListener(map, 'click', function () { if (shiftKeyPressed == false) { clearSelection(); selectedShape = null; } }); //Keyboard shortcuts document.addEventListener('keydown', function () { if (event.code == 'KeyY' && (event.ctrlKey || event.metaKey) || (event.code == 'KeyZ' && event.code == 'ShiftLeft' && (event.ctrlKey || event.metaKey) )){ redo(); } if (event.code == 'KeyZ' && (event.ctrlKey || event.metaKey)){ if(shiftKeyPressed == false) { undo(); } } if (event.code == 'KeyA' && (event.ctrlKey || event.metaKey)){ event.preventDefault(); selectAll(); drawingManager.setDrawingMode(null); } if (event.code == 'KeyD' && (event.ctrlKey || event.metaKey)){ event.preventDefault(); deselectAll(); } if (event.code == 'Digit0' || event.code == 'Numpad0' || event.code == 'Backquote') { //clearSelection(); drawingManager.setDrawingMode(null); } else if (event.code == 'Digit1') { drawingManager.setDrawingMode('marker'); } else if (event.code == 'Digit2') { drawingManager.setDrawingMode('circle'); } else if (event.code == 'Digit3') { drawingManager.setDrawingMode('polygon'); } else if (event.code == 'Digit4') { drawingManager.setDrawingMode('polyline'); } else if (event.code == 'Digit5') { drawingManager.setDrawingMode('rectangle'); } else if (event.code == 'KeyQ') { printHistory(); } // console.log(event.code); }); //Sets shift as pressed document.addEventListener('keydown', function () { if (event.code == 'ShiftLeft' || event.code == 'ShiftRight') { shiftKeyPressed = true; } }); //Sets shift as unpressed document.addEventListener('keyup', function () { if (event.code == 'ShiftLeft' || event.code == 'ShiftRight') { shiftKeyPressed = false; } }); buildColorPalette(); } //Deletes a vertex if clicked on it function vertexAndPolyDel(e, newShape) { var vertex = e.vertex; //console.log(e) if (e.vertex !== undefined) { historyOverlayPush(); if (newShape.type === google.maps.drawing.OverlayType.POLYGON) { var path = newShape.getPaths().getAt(e.path); path.removeAt(e.vertex); if (path.length < 3) { newShape.setMap(null); } } if (newShape.type === google.maps.drawing.OverlayType.POLYLINE) { var path = newShape.getPath(); path.removeAt(e.vertex); if (path.length < 2) { newShape.setMap(null); } } presentOverlayPush(); } } function addMarkerListeners(newShape,e) { //cLICK EVENT IF A MARKER IS CREATED google.maps.event.addListener(newShape, 'click', function (e) { setSelection(newShape, e); }); google.maps.event.addListener(newShape, 'dragstart', function (e) { beingDragged = true; historyOverlayPush(); }); google.maps.event.addListener(newShape, 'dragend', function () { beingDragged = false; presentOverlayPush(); allowDeselect = false; }); } function addShapeListeners(newShape,e) { // Add an event listener that selects the newly-drawn shape when the user // mouses down on it. google.maps.event.addListener(newShape, 'click', function (e) { vertexAndPolyDel(e, newShape); }); google.maps.event.addListener(newShape, 'drag', function (e) { //for(var i = 0; i < selectedShapes.length; i++) { // if(newShape.type = 'rectangle') { // var newBounds = { // east: selectedShapes[i].getBounds().ea.l + (selectedShapes[i].getBounds().ea.l - faj), // north: selectedShapes[i].getBounds().la.l + (selectedShapes[i].getBounds().la.l - fal), // south: selectedShapes[i].getBounds().la.j + (selectedShapes[i].getBounds().la.j - maj), // west: selectedShapes[i].getBounds().ea.j + (selectedShapes[i].getBounds().ea.j - mal) // } // selectedShapes[i].set // } else { // } // //} }); google.maps.event.addListener(newShape, 'dragstart', function (e) { //console.log(newShape.bounds); beingDragged = true; historyOverlayPush(); }); google.maps.event.addListener(newShape, 'dragend', function () { beingDragged = false; presentOverlayPush(); allowDeselect = false; }); //Store information after the event ends google.maps.event.addListener(newShape, 'bounds_changed', function (e) { if (beingDragged == false){ resizeEntry = true; presentOverlayPush(); resizeEntry = false; } }); //Add an event listener to select a shape if the mouse hovers over it google.maps.event.addListener(newShape, 'mousedown', function (e) { if (e.vertex !== undefined || e.edge !== undefined) { historyOverlayPush() } if (drawingManager.drawingMode == null) { setSelection(newShape, e); } }); google.maps.event.addListener(newShape, 'mouseup', function (e) { if (e.vertex !== undefined || e.edge !== undefined) { presentOverlayPush() } else{ removeFromSelectedShapes(newShape); } }); } function clearSelection() { if (selectedShape) { if (selectedShape.type !== 'marker') { selectedShape.setEditable(false); if (shiftKeyPressed == false) { for (var i = 0; i < selectedShapes.length; i++) { selectedShapes[i].setEditable(false); } selectedShapes = []; } } selectedShape = null; } } //Set selection for the selected overlay function setSelection(shape, e) { if (shape.type !== 'marker') { if (shiftKeyPressed == false) { if (e.vertex == undefined) { if(e.edge == undefined) { clearSelection(); shape.setEditable(true); } } } if (selectedShapes.includes(shape)) { if(e.vertex == undefined ) { if(e.edge == undefined) { //removeFromSelectedShapes(shape); } } } else { shape.setEditable(true); selectedShapes.push(shape); } //Send the values to be updated var thi = shape.strokeWeight; var opa = shape.fillOpacity; var fCol = shape.fillColor; var sCol = shape.strokeColor; updateMenuValues(thi, opa, fCol, sCol); } else if (shape.type == 'marker') { clearSelection(); } selectedShape = shape; } function removeFromSelectedShapes(shape) { if (selectedShapes.includes(shape)) { if(allowDeselect) { const index = selectedShapes.indexOf(shape); selectedShapes.splice(index, 1); shape.setEditable(false); } allowDeselect = false; } } //Set selected thickness function setSelectedThickness(sWeight) { if (selectedShapes.length > 0) { //historyOverlayPush(); for (var i = 0; i < selectedShapes.length; i++) { selectedShapes[i].set('strokeWeight', sWeight); //console.log(selectedShapes.length); } } } //Set selected opacity function setSelectedOpacity(fOpacity) { if (selectedShapes.length > 0) { for (var i = 0; i < selectedShapes.length; i++) { selectedShapes[i].set('fillOpacity', fOpacity); } } } //set selected fill colour function setSelectedShapeColor(color) { if (selectedShapes.length > 0) { for (var i = 0; i < selectedShapes.length; i++) { selectedShapes[i].set('fillColor', color); selectedShapes[i].set('strokeColor', color); } } } function updateMenuValues(thi, opa, fCol, sCol) { //Update thickness slider and value on the settings menu var thicknessSliderOutput = document.getElementById("thicknessRangeVal"); thicknessSliderOutput.innerHTML = thi; document.getElementById("thicknessRange").value = thi * 20; //Update the opacity slider and value on the settings menu var opacitySliderOutput = document.getElementById("opacityRangeVal"); opacitySliderOutput.innerHTML = "% " + opa * 100; document.getElementById("colourOpacity").value = opa * 100; if (drawingManager.drawingMode == null) { selectColor(fCol); } } function selectAll(){ shiftKeyPressed = true; var e = new Object(); e.vertex = undefined; selectedShapes = []; for(var i = 0; i< overlays.length; i++) { setSelection(overlays[i], e); } shiftKeyPressed = false; } function deselectAll(){ for(var i = 0; i < selectedShapes.length; i++) { selectedShapes[i].setEditable(false); } selectedShapes = []; } function printHistory() { console.log("prev", prevOverlays); console.log("present ", presentOverlays); console.log("undone ", undoneOverlays); } function deleteSelectedShape() { historyOverlayPush(); for (var i = 0; i < selectedShapes.length; i++) { selectedShapes[i].setMap(null); if (overlays.includes(selectedShapes[i])) { const index = overlays.indexOf(selectedShapes[i]); overlays.splice(index, 1); selectedShapes[i].setEditable(false); } } selectedShapes = []; presentOverlayPush(); } function deleteAllShape() { historyOverlayPush(); for (var i = 0; i < overlays.length; i++) { overlays[i].setMap(null); } overlays = []; presentOverlayPush(); }