From 0d8a50762009188f3e7b64c7300773dda85e46f6 Mon Sep 17 00:00:00 2001 From: Fedor Katurov Date: Wed, 15 Aug 2018 18:00:20 +0700 Subject: [PATCH] stickers and sticker deleting --- src/constants/providers.js | 2 +- src/modules/Editor.js | 2 +- src/modules/Map.js | 2 +- src/modules/Poly.js | 1 - src/modules/Sticker.js | 91 ++++++++++++++++++++++++++++------ src/modules/Stickers.js | 1 + src/styles/mapScreen.js | 81 ++++++++++++++++++++++++++++-- src/utils/leafletDomMarkers.js | 2 +- 8 files changed, 160 insertions(+), 22 deletions(-) diff --git a/src/constants/providers.js b/src/constants/providers.js index 7035606..0586d57 100644 --- a/src/constants/providers.js +++ b/src/constants/providers.js @@ -2,7 +2,7 @@ export const providers = { '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', - '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', 'hot': 'http://{s}.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png', 'blank': 'http://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png', diff --git a/src/modules/Editor.js b/src/modules/Editor.js index 3ed571c..f02957e 100644 --- a/src/modules/Editor.js +++ b/src/modules/Editor.js @@ -27,7 +27,7 @@ export class Editor { [MODES.STICKERS]: this.stickers.createOnClick }; - this.map.map.on('click', this.onClick); + this.map.map.addEventListener('mousedown', this.onClick); } changeMode = mode => { diff --git a/src/modules/Map.js b/src/modules/Map.js index ee001d2..6f92870 100644 --- a/src/modules/Map.js +++ b/src/modules/Map.js @@ -8,7 +8,7 @@ export class Map { constructor({ container }) { 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: 'Независимое Велосообщество', maxNativeZoom: 18, maxZoom: 18, diff --git a/src/modules/Poly.js b/src/modules/Poly.js index dd7fabb..aae234c 100644 --- a/src/modules/Poly.js +++ b/src/modules/Poly.js @@ -51,7 +51,6 @@ export class Poly { 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(); diff --git a/src/modules/Sticker.js b/src/modules/Sticker.js index 3714514..fe7b1cc 100644 --- a/src/modules/Sticker.js +++ b/src/modules/Sticker.js @@ -4,31 +4,45 @@ import 'leaflet-editable'; import { DomMarker } from '$utils/leafletDomMarkers'; export class Sticker { - constructor({ latlng, deleteSticker }) { + constructor({ + latlng, deleteSticker, map + }) { + this.angle = 2.2; this.isDragging = false; + this.map = map; this.deleteSticker = deleteSticker; + 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'); - stickerImage.innerHTML = '
'; + this.element.className = 'sticker-container'; + this.stickerImage.className = 'sticker-label'; + this.stickerArrow.className = 'sticker-arrow'; + this.stickerDelete.className = 'sticker-delete'; - const stickerArrow = document.createElement('div'); - stickerArrow.innerHTML = '
'; - - this.element.appendChild(stickerArrow); - this.element.appendChild(stickerImage); + this.element.appendChild(this.stickerArrow); + this.element.appendChild(this.stickerImage); + this.element.appendChild(this.stickerDelete); const marker = new DomMarker({ element: this.element, + className: 'sticker-container', }); this.sticker = L.marker(latlng, { icon: marker }); - stickerImage.addEventListener('mousedown', this.onDragStart); - stickerImage.addEventListener('mouseup', this.onDragStop); - // - // this.sticker.addEventListener('click', this.onDelete); + this.stickerImage.addEventListener('mousedown', this.onDragStart); + this.stickerImage.addEventListener('mouseup', this.onDragStop); + this.stickerImage.addEventListener('click', this.preventPropagations); + + this.element.addEventListener('mousedown', this.preventPropagations); + + this.setAngle(this.angle); + + this.stickerDelete.addEventListener('click', this.onDelete); } onDelete = () => { @@ -36,14 +50,63 @@ export class Sticker { }; onDragStart = e => { + this.preventPropagations(e); + this.isDragging = true; 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 => { + this.preventPropagations(e); + this.isDragging = false; 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)`; } } diff --git a/src/modules/Stickers.js b/src/modules/Stickers.js index 532c7dc..2edf735 100644 --- a/src/modules/Stickers.js +++ b/src/modules/Stickers.js @@ -22,6 +22,7 @@ export class Stickers { const sticker = new Sticker({ latlng, deleteSticker: this.deleteStickerByReference, + map: this.map, }); this.stickers.push(sticker); diff --git a/src/styles/mapScreen.js b/src/styles/mapScreen.js index 5fe381f..14a91c2 100644 --- a/src/styles/mapScreen.js +++ b/src/styles/mapScreen.js @@ -29,6 +29,38 @@ const vertexMixin = 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 { width: 48px; height: 48px; @@ -37,13 +69,56 @@ const stickers = css` border-radius: 32px; left: 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 { - width: 24px; - height: 24px; + .sticker-arrow { position: absolute; 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; + } } `; diff --git a/src/utils/leafletDomMarkers.js b/src/utils/leafletDomMarkers.js index 19b27e7..5aebc78 100644 --- a/src/utils/leafletDomMarkers.js +++ b/src/utils/leafletDomMarkers.js @@ -11,7 +11,7 @@ export const DomMarker = L.DivIcon.extend({ }, createIcon: function() { - const { html, element } = this.options; + const { html, element, className } = this.options; this._setIconStyles(element, 'icon');