mirror of
https://github.com/muerwre/orchidmap-front.git
synced 2025-05-06 00:16:40 +07:00
stickers with ability to drag them
This commit is contained in:
parent
5f30df6f48
commit
b8434c32e7
19 changed files with 460 additions and 39 deletions
57
src/modules/Editor.js
Normal file
57
src/modules/Editor.js
Normal file
|
@ -0,0 +1,57 @@
|
|||
import { Map } from '$modules/Map';
|
||||
import { Poly } from "$modules/Poly";
|
||||
import { MODES } from '$constants/modes';
|
||||
import { Stickers } from '$modules/Stickers';
|
||||
|
||||
export class Editor {
|
||||
constructor({
|
||||
container,
|
||||
mode,
|
||||
setMode
|
||||
}) {
|
||||
this.map = new Map({ container });
|
||||
this.poly = new Poly({ map: this.map.map });
|
||||
this.stickers = new Stickers({ map: this.map.map });
|
||||
|
||||
this.setMode = setMode;
|
||||
this.mode = mode;
|
||||
|
||||
this.switches = {
|
||||
[MODES.POLY]: {
|
||||
start: this.poly.continue,
|
||||
stop: this.poly.stop,
|
||||
}
|
||||
};
|
||||
|
||||
this.clickHandlers = {
|
||||
[MODES.STICKERS]: this.stickers.createOnClick
|
||||
};
|
||||
|
||||
this.map.map.on('click', this.onClick);
|
||||
}
|
||||
|
||||
changeMode = mode => {
|
||||
if (this.mode === mode) {
|
||||
this.disableMode(mode);
|
||||
this.setMode(MODES.NONE);
|
||||
this.mode = MODES.NONE;
|
||||
} else {
|
||||
this.disableMode(this.mode);
|
||||
this.setMode(mode);
|
||||
this.mode = mode;
|
||||
this.enableMode(mode);
|
||||
}
|
||||
};
|
||||
|
||||
enableMode = mode => {
|
||||
if (this.switches[mode] && this.switches[mode].start) this.switches[mode].start();
|
||||
};
|
||||
|
||||
disableMode = mode => {
|
||||
if (this.switches[mode] && this.switches[mode].stop) this.switches[mode].stop();
|
||||
};
|
||||
|
||||
onClick = e => {
|
||||
if (this.clickHandlers[this.mode]) this.clickHandlers[this.mode](e);
|
||||
};
|
||||
}
|
19
src/modules/Map.js
Normal file
19
src/modules/Map.js
Normal file
|
@ -0,0 +1,19 @@
|
|||
import L from 'leaflet';
|
||||
import { providers } from '$constants/providers';
|
||||
|
||||
import 'leaflet/dist/leaflet.css';
|
||||
import 'leaflet-editable';
|
||||
|
||||
export class Map {
|
||||
constructor({ container }) {
|
||||
this.map = L.map(container, { editable: true }).setView([55.0153275, 82.9071235], 13);
|
||||
|
||||
this.tileLayer = L.tileLayer(providers.default, {
|
||||
attribution: 'Независимое Велосообщество',
|
||||
maxNativeZoom: 18,
|
||||
maxZoom: 18,
|
||||
});
|
||||
|
||||
this.tileLayer.addTo(this.map);
|
||||
}
|
||||
}
|
70
src/modules/Poly.js
Normal file
70
src/modules/Poly.js
Normal file
|
@ -0,0 +1,70 @@
|
|||
import L from "leaflet";
|
||||
|
||||
const polyStyle = { color: '#ff3333', weight: '5' };
|
||||
|
||||
export class Poly {
|
||||
constructor({ map }) {
|
||||
this.poly = L.polyline([], polyStyle);
|
||||
this.latlngs = [];
|
||||
this.poly.addTo(map);
|
||||
this.map = map;
|
||||
|
||||
this.bindEvents();
|
||||
}
|
||||
|
||||
updateMarks = () => {
|
||||
const coords = this.poly.toGeoJSON().geometry.coordinates;
|
||||
this.latlngs = (coords && coords.length && coords.map(([lng, lat]) => ({ lng, lat }))) || [];
|
||||
};
|
||||
|
||||
bindEvents = () => {
|
||||
// Если на карте что-то меняется, пересчитать километражи
|
||||
this.map.editTools.addEventListener('editable:drawing:mouseup', this.updateMarks);
|
||||
this.map.editTools.addEventListener('editable:vertex:dragend', this.updateMarks);
|
||||
this.map.editTools.addEventListener('editable:vertex:deleted', this.updateMarks);
|
||||
this.map.editTools.addEventListener('editable:vertex:new', this.updateMarks);
|
||||
|
||||
// После удаления точки - продолжить рисование
|
||||
this.map.editTools.addEventListener('editable:vertex:deleted', this.continueForward);
|
||||
//
|
||||
// map.editTools.addEventListener('editable:vertex:dragend', e => writeReduxData({ e, updatePolyCoords }));
|
||||
// map.editTools.addEventListener('editable:vertex:new', e => writeReduxData({ e, updatePolyCoords }));
|
||||
// map.editTools.addEventListener('editable:vertex:deleted', e => writeReduxData({ e, updatePolyCoords }));
|
||||
|
||||
// Продолжить рисование после удаления точки
|
||||
// map.editTools.addEventListener('editable:vertex:deleted', e => {
|
||||
// poly.editor.continueForward();
|
||||
// updateMarks();
|
||||
// });
|
||||
|
||||
// Добавлять точек в полилинию по щелчку
|
||||
// map.editTools.addEventListener('editable:drawing:click', e => insertVertex({ e, updatePolyCoords }));
|
||||
// map.editTools.addEventListener('editable:drawing:clicked', () => updateMarks({ updatePolyCoords }));
|
||||
|
||||
// Это для точек. При перетаскивании конца указателя тащим точку
|
||||
// map.editTools.addEventListener('editable:vertex:drag', on_vertex_drag);
|
||||
|
||||
// при перетаскивании ручек убирать все отметки километров
|
||||
// map.editTools.addEventListener('editable:vertex:dragstart', clearKmMarks);
|
||||
};
|
||||
|
||||
continue = () => {
|
||||
if (this.latlngs && this.latlngs.length) {
|
||||
this.poly.enableEdit().continueForward();
|
||||
this.poly.editor.options.skipMiddleMarkers = true;
|
||||
this.poly.editor.reset();
|
||||
} else {
|
||||
this.poly = this.map.editTools.startPolyline();
|
||||
this.poly.setStyle(polyStyle);
|
||||
}
|
||||
};
|
||||
|
||||
stop = () => {
|
||||
if (this.map.editTools) this.map.editTools.stopDrawing();
|
||||
};
|
||||
|
||||
continueForward = () => {
|
||||
if (!this.poly.editor) return;
|
||||
this.poly.editor.continueForward();
|
||||
};
|
||||
}
|
49
src/modules/Sticker.js
Normal file
49
src/modules/Sticker.js
Normal file
|
@ -0,0 +1,49 @@
|
|||
import L from 'leaflet';
|
||||
import 'leaflet-editable';
|
||||
|
||||
import { DomMarker } from '$utils/leafletDomMarkers';
|
||||
|
||||
export class Sticker {
|
||||
constructor({ latlng, deleteSticker }) {
|
||||
this.isDragging = false;
|
||||
|
||||
this.deleteSticker = deleteSticker;
|
||||
this.element = document.createElement('div');
|
||||
|
||||
const stickerImage = document.createElement('div');
|
||||
stickerImage.innerHTML = '<div class="sticker-label" />';
|
||||
|
||||
const stickerArrow = document.createElement('div');
|
||||
stickerArrow.innerHTML = '<div class="sticker-arrow" />';
|
||||
|
||||
this.element.appendChild(stickerArrow);
|
||||
this.element.appendChild(stickerImage);
|
||||
|
||||
const marker = new DomMarker({
|
||||
element: this.element,
|
||||
});
|
||||
|
||||
this.sticker = L.marker(latlng, { icon: marker });
|
||||
|
||||
stickerImage.addEventListener('mousedown', this.onDragStart);
|
||||
stickerImage.addEventListener('mouseup', this.onDragStop);
|
||||
//
|
||||
// this.sticker.addEventListener('click', this.onDelete);
|
||||
}
|
||||
|
||||
onDelete = () => {
|
||||
if (!this.isDragging) this.deleteSticker(this);
|
||||
};
|
||||
|
||||
onDragStart = e => {
|
||||
this.isDragging = true;
|
||||
this.sticker.disableEdit();
|
||||
console.log('dragStart');
|
||||
};
|
||||
|
||||
onDragStop = e => {
|
||||
this.isDragging = false;
|
||||
this.sticker.enableEdit();
|
||||
console.log('dragStop');
|
||||
}
|
||||
}
|
40
src/modules/Stickers.js
Normal file
40
src/modules/Stickers.js
Normal file
|
@ -0,0 +1,40 @@
|
|||
import L from 'leaflet';
|
||||
import { Sticker } from '$modules/Sticker';
|
||||
|
||||
export class Stickers {
|
||||
constructor({ map }) {
|
||||
this.map = map;
|
||||
this.layer = L.layerGroup();
|
||||
|
||||
this.stickers = [];
|
||||
|
||||
this.layer.addTo(this.map);
|
||||
}
|
||||
|
||||
createOnClick = e => {
|
||||
if (!e || !e.latlng) return;
|
||||
|
||||
const { latlng } = e;
|
||||
this.createSticker({ latlng });
|
||||
};
|
||||
|
||||
createSticker = ({ latlng }) => {
|
||||
const sticker = new Sticker({
|
||||
latlng,
|
||||
deleteSticker: this.deleteStickerByReference,
|
||||
});
|
||||
this.stickers.push(sticker);
|
||||
|
||||
sticker.sticker.addTo(this.map);
|
||||
sticker.sticker.enableEdit();
|
||||
};
|
||||
|
||||
deleteStickerByReference = ref => {
|
||||
const index = this.stickers.indexOf(ref);
|
||||
|
||||
if (index < 0) return;
|
||||
|
||||
this.map.removeLayer(ref.sticker);
|
||||
this.stickers.splice(index, 1);
|
||||
};
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
import L from "leaflet";
|
||||
|
||||
import { providers } from "$constants/providers";
|
||||
|
||||
import 'leaflet/dist/leaflet.css';
|
||||
|
||||
export class Map {
|
||||
constructor(container) {
|
||||
this.map = L.map(container, {
|
||||
editable: true,
|
||||
layers: [
|
||||
|
||||
]
|
||||
}).setView([55.0153275, 82.9071235], 13);
|
||||
|
||||
this.tileLayer = L.tileLayer(providers.default, {
|
||||
attribution: 'Независимое Велосообщество',
|
||||
maxNativeZoom: 18,
|
||||
maxZoom: 18,
|
||||
}).addTo(this.map);
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue