mirror of
https://github.com/muerwre/orchidmap-front.git
synced 2025-04-25 02:56:41 +07:00
stickers and sticker deleting
This commit is contained in:
parent
b8434c32e7
commit
0d8a507620
8 changed files with 160 additions and 22 deletions
|
@ -2,7 +2,7 @@
|
||||||
export const providers = {
|
export const providers = {
|
||||||
'watercolor': 'http://stamen-tiles-{s}.a.ssl.fastly.net/watercolor/{z}/{x}/{y}.jpg',
|
'watercolor': 'http://stamen-tiles-{s}.a.ssl.fastly.net/watercolor/{z}/{x}/{y}.jpg',
|
||||||
'darq': 'http://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png',
|
'darq': 'http://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png',
|
||||||
'2gis': 'https://tile1.maps.2gis.com/tiles?x={x}&y={y}&z={z}&v=1',
|
'dgis': 'https://tile1.maps.2gis.com/tiles?x={x}&y={y}&z={z}&v=1',
|
||||||
'default': 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
|
'default': 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
|
||||||
'hot': 'http://{s}.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png',
|
'hot': 'http://{s}.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png',
|
||||||
'blank': 'http://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png',
|
'blank': 'http://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png',
|
||||||
|
|
|
@ -27,7 +27,7 @@ export class Editor {
|
||||||
[MODES.STICKERS]: this.stickers.createOnClick
|
[MODES.STICKERS]: this.stickers.createOnClick
|
||||||
};
|
};
|
||||||
|
|
||||||
this.map.map.on('click', this.onClick);
|
this.map.map.addEventListener('mousedown', this.onClick);
|
||||||
}
|
}
|
||||||
|
|
||||||
changeMode = mode => {
|
changeMode = mode => {
|
||||||
|
|
|
@ -8,7 +8,7 @@ export class Map {
|
||||||
constructor({ container }) {
|
constructor({ container }) {
|
||||||
this.map = L.map(container, { editable: true }).setView([55.0153275, 82.9071235], 13);
|
this.map = L.map(container, { editable: true }).setView([55.0153275, 82.9071235], 13);
|
||||||
|
|
||||||
this.tileLayer = L.tileLayer(providers.default, {
|
this.tileLayer = L.tileLayer(providers.dgis, {
|
||||||
attribution: 'Независимое Велосообщество',
|
attribution: 'Независимое Велосообщество',
|
||||||
maxNativeZoom: 18,
|
maxNativeZoom: 18,
|
||||||
maxZoom: 18,
|
maxZoom: 18,
|
||||||
|
|
|
@ -51,7 +51,6 @@ export class Poly {
|
||||||
continue = () => {
|
continue = () => {
|
||||||
if (this.latlngs && this.latlngs.length) {
|
if (this.latlngs && this.latlngs.length) {
|
||||||
this.poly.enableEdit().continueForward();
|
this.poly.enableEdit().continueForward();
|
||||||
this.poly.editor.options.skipMiddleMarkers = true;
|
|
||||||
this.poly.editor.reset();
|
this.poly.editor.reset();
|
||||||
} else {
|
} else {
|
||||||
this.poly = this.map.editTools.startPolyline();
|
this.poly = this.map.editTools.startPolyline();
|
||||||
|
|
|
@ -4,31 +4,45 @@ import 'leaflet-editable';
|
||||||
import { DomMarker } from '$utils/leafletDomMarkers';
|
import { DomMarker } from '$utils/leafletDomMarkers';
|
||||||
|
|
||||||
export class Sticker {
|
export class Sticker {
|
||||||
constructor({ latlng, deleteSticker }) {
|
constructor({
|
||||||
|
latlng, deleteSticker, map
|
||||||
|
}) {
|
||||||
|
this.angle = 2.2;
|
||||||
this.isDragging = false;
|
this.isDragging = false;
|
||||||
|
this.map = map;
|
||||||
|
|
||||||
this.deleteSticker = deleteSticker;
|
this.deleteSticker = deleteSticker;
|
||||||
|
|
||||||
this.element = document.createElement('div');
|
this.element = document.createElement('div');
|
||||||
|
this.stickerImage = document.createElement('div');
|
||||||
|
this.stickerArrow = document.createElement('div');
|
||||||
|
this.stickerDelete = document.createElement('div');
|
||||||
|
|
||||||
const stickerImage = document.createElement('div');
|
this.element.className = 'sticker-container';
|
||||||
stickerImage.innerHTML = '<div class="sticker-label" />';
|
this.stickerImage.className = 'sticker-label';
|
||||||
|
this.stickerArrow.className = 'sticker-arrow';
|
||||||
|
this.stickerDelete.className = 'sticker-delete';
|
||||||
|
|
||||||
const stickerArrow = document.createElement('div');
|
this.element.appendChild(this.stickerArrow);
|
||||||
stickerArrow.innerHTML = '<div class="sticker-arrow" />';
|
this.element.appendChild(this.stickerImage);
|
||||||
|
this.element.appendChild(this.stickerDelete);
|
||||||
this.element.appendChild(stickerArrow);
|
|
||||||
this.element.appendChild(stickerImage);
|
|
||||||
|
|
||||||
const marker = new DomMarker({
|
const marker = new DomMarker({
|
||||||
element: this.element,
|
element: this.element,
|
||||||
|
className: 'sticker-container',
|
||||||
});
|
});
|
||||||
|
|
||||||
this.sticker = L.marker(latlng, { icon: marker });
|
this.sticker = L.marker(latlng, { icon: marker });
|
||||||
|
|
||||||
stickerImage.addEventListener('mousedown', this.onDragStart);
|
this.stickerImage.addEventListener('mousedown', this.onDragStart);
|
||||||
stickerImage.addEventListener('mouseup', this.onDragStop);
|
this.stickerImage.addEventListener('mouseup', this.onDragStop);
|
||||||
//
|
this.stickerImage.addEventListener('click', this.preventPropagations);
|
||||||
// this.sticker.addEventListener('click', this.onDelete);
|
|
||||||
|
this.element.addEventListener('mousedown', this.preventPropagations);
|
||||||
|
|
||||||
|
this.setAngle(this.angle);
|
||||||
|
|
||||||
|
this.stickerDelete.addEventListener('click', this.onDelete);
|
||||||
}
|
}
|
||||||
|
|
||||||
onDelete = () => {
|
onDelete = () => {
|
||||||
|
@ -36,14 +50,63 @@ export class Sticker {
|
||||||
};
|
};
|
||||||
|
|
||||||
onDragStart = e => {
|
onDragStart = e => {
|
||||||
|
this.preventPropagations(e);
|
||||||
|
|
||||||
this.isDragging = true;
|
this.isDragging = true;
|
||||||
this.sticker.disableEdit();
|
this.sticker.disableEdit();
|
||||||
console.log('dragStart');
|
|
||||||
|
window.addEventListener('mousemove', this.onDrag);
|
||||||
|
window.addEventListener('mouseup', this.onDragStop);
|
||||||
|
};
|
||||||
|
|
||||||
|
preventPropagations = e => {
|
||||||
|
if (!e || !e.stopPropagation) return;
|
||||||
|
|
||||||
|
e.stopPropagation();
|
||||||
|
e.preventDefault();
|
||||||
};
|
};
|
||||||
|
|
||||||
onDragStop = e => {
|
onDragStop = e => {
|
||||||
|
this.preventPropagations(e);
|
||||||
|
|
||||||
this.isDragging = false;
|
this.isDragging = false;
|
||||||
this.sticker.enableEdit();
|
this.sticker.enableEdit();
|
||||||
console.log('dragStop');
|
|
||||||
|
window.removeEventListener('mousemove', this.onDrag);
|
||||||
|
window.removeEventListener('mouseup', this.onDragStop);
|
||||||
|
};
|
||||||
|
|
||||||
|
onDrag = e => {
|
||||||
|
this.preventPropagations(e);
|
||||||
|
this.estimateAngle(e);
|
||||||
|
};
|
||||||
|
|
||||||
|
estimateAngle = e => {
|
||||||
|
console.log('est');
|
||||||
|
const { x, y } = this.element.getBoundingClientRect();
|
||||||
|
const { pageX, pageY } = e;
|
||||||
|
this.angle = Math.atan2((y - pageY), (x - pageX));
|
||||||
|
|
||||||
|
this.setAngle(this.angle);
|
||||||
|
};
|
||||||
|
|
||||||
|
setAngle = angle => {
|
||||||
|
// $(active_sticker.container).css('left',6+x-parseInt(active_sticker.ctrl.css('left'))).css('top',6+y-parseInt(active_sticker.ctrl.css('top')));
|
||||||
|
//
|
||||||
|
const rad = 30;
|
||||||
|
const mrad = 48;
|
||||||
|
const x = ((Math.cos(angle + 3.14) * rad) - 30);
|
||||||
|
const y = ((Math.sin(angle + 3.14) * rad) - 30);
|
||||||
|
|
||||||
|
const ax = ((Math.cos(angle + 3.4) * mrad) - 12);
|
||||||
|
const ay = ((Math.sin(angle + 3.4) * mrad) - 12);
|
||||||
|
|
||||||
|
this.stickerImage.style.left = 6 + x;
|
||||||
|
this.stickerImage.style.top = 6 + y;
|
||||||
|
|
||||||
|
this.stickerDelete.style.left = ax;
|
||||||
|
this.stickerDelete.style.top = ay;
|
||||||
|
|
||||||
|
this.stickerArrow.style.transform = `rotate(${angle + 3.14}rad)`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ export class Stickers {
|
||||||
const sticker = new Sticker({
|
const sticker = new Sticker({
|
||||||
latlng,
|
latlng,
|
||||||
deleteSticker: this.deleteStickerByReference,
|
deleteSticker: this.deleteStickerByReference,
|
||||||
|
map: this.map,
|
||||||
});
|
});
|
||||||
this.stickers.push(sticker);
|
this.stickers.push(sticker);
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,38 @@ const vertexMixin = css`
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const stickers = css`
|
const stickers = css`
|
||||||
|
.sticker-container {
|
||||||
|
outline: none;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
::before {
|
||||||
|
content: ' ';
|
||||||
|
box-shadow: 0 0 10px 1px #ff3344;
|
||||||
|
background: #ff334422;
|
||||||
|
width: 48px;
|
||||||
|
height: 48px;
|
||||||
|
left: -24px;
|
||||||
|
top: -24px;
|
||||||
|
position: absolute;
|
||||||
|
border-radius: 40px;
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 250ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
:hover {
|
||||||
|
.sticker-delete {
|
||||||
|
transform: scale(1);
|
||||||
|
pointer-events: all;
|
||||||
|
}
|
||||||
|
|
||||||
|
::before {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
.sticker-label {
|
.sticker-label {
|
||||||
width: 48px;
|
width: 48px;
|
||||||
height: 48px;
|
height: 48px;
|
||||||
|
@ -37,13 +69,56 @@ const stickers = css`
|
||||||
border-radius: 32px;
|
border-radius: 32px;
|
||||||
left: 0;
|
left: 0;
|
||||||
top: 0;
|
top: 0;
|
||||||
|
outline: none;
|
||||||
|
|
||||||
|
::after {
|
||||||
|
content: ' ';
|
||||||
|
box-shadow: 0 0 0 1px #ff3344;
|
||||||
|
width: 80px;
|
||||||
|
height: 80px;
|
||||||
|
left: ${24 - 40}px;
|
||||||
|
top: ${24 - 40}px;
|
||||||
|
position: absolute;
|
||||||
|
border-radius: 40px;
|
||||||
|
pointer-events: none;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.sticker-arrow {
|
.sticker-arrow {
|
||||||
width: 24px;
|
|
||||||
height: 24px;
|
|
||||||
position: absolute;
|
position: absolute;
|
||||||
background: red;
|
background: red;
|
||||||
|
transform-origin: 0 0;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
|
||||||
|
::after {
|
||||||
|
content: ' ';
|
||||||
|
background: #ff3344;
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
transform-origin: 0 0;
|
||||||
|
transform: rotate(-45deg);
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.sticker-delete {
|
||||||
|
position: absolute;
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
background: red;
|
||||||
|
border-radius: 24px;
|
||||||
|
transition: transform 500ms;
|
||||||
|
transform: scale(0);
|
||||||
|
opacity: 1;
|
||||||
|
pointer-events: none;
|
||||||
|
|
||||||
|
:hover {
|
||||||
|
transform: scale(1.2) !important;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ export const DomMarker = L.DivIcon.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
createIcon: function() {
|
createIcon: function() {
|
||||||
const { html, element } = this.options;
|
const { html, element, className } = this.options;
|
||||||
|
|
||||||
this._setIconStyles(element, 'icon');
|
this._setIconStyles(element, 'icon');
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue