stickers with ability to drag them

This commit is contained in:
Fedor Katurov 2018-08-15 16:18:49 +07:00
parent 5f30df6f48
commit b8434c32e7
19 changed files with 460 additions and 39 deletions

57
src/modules/Editor.js Normal file
View 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
View 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
View 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
View 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
View 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);
};
}

View file

@ -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);
}
}