import { marker } from 'leaflet'; import 'leaflet-editable'; import { DomMarker } from '$utils/DomMarker'; import stickers from '$sprites/stickers.svg'; import { STICKERS } from '$constants/stickers'; export class Sticker { constructor({ latlng, deleteSticker, map, lockMapClicks, sticker, triggerOnChange, angle = 2.2 }) { this.latlng = latlng; this.angle = angle; this.isDragging = false; this.map = map; this.sticker = sticker; this.editable = true; this.triggerOnChange = triggerOnChange; this.deleteSticker = deleteSticker; this.lockMapClicks = lockMapClicks; this.element = document.createElement('div'); this.stickerImage = document.createElement('div'); this.stickerArrow = document.createElement('div'); this.stickerDelete = document.createElement('div'); this.element.className = 'sticker-container'; this.stickerImage.className = 'sticker-label'; this.stickerArrow.className = 'sticker-arrow'; this.stickerDelete.className = 'sticker-delete'; this.stickerImage.innerHTML = this.generateStickerSVG(sticker); this.element.appendChild(this.stickerArrow); this.element.appendChild(this.stickerImage); this.element.appendChild(this.stickerDelete); const mark = new DomMarker({ element: this.element, className: 'sticker-container', }); this.marker = marker(latlng, { icon: mark }); this.setAngle(angle); this.stickerImage.addEventListener('mousedown', this.onDragStart); this.stickerImage.addEventListener('mouseup', this.onDragStop); this.element.addEventListener('mouseup', this.preventPropagations); this.stickerDelete.addEventListener('click', this.onDelete); this.marker.addEventListener('dragend', this.triggerOnChange); this.triggerOnChange(); } onDelete = () => { this.triggerOnChange(); if (!this.isDragging) this.deleteSticker(this); }; onDragStart = e => { this.preventPropagations(e); this.isDragging = true; this.marker.disableEdit(); this.lockMapClicks(true); 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.triggerOnChange(); this.isDragging = false; this.marker.enableEdit(); window.removeEventListener('mousemove', this.onDrag); window.removeEventListener('mouseup', this.onDragStop); this.lockMapClicks(false); }; onDrag = e => { this.preventPropagations(e); this.estimateAngle(e); }; estimateAngle = e => { const { x, y } = this.element.getBoundingClientRect(); const { pageX, pageY } = e; this.angle = Math.atan2((y - pageY), (x - pageX)); this.setAngle(this.angle); }; setAngle = angle => { const rad = 44; const mrad = 76; 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)`; }; generateStickerSVG = ({ set, sticker }) => ( // ` // // // // ` `
` ); dumpData = () => ({ angle: this.angle, latlng: { ...this.marker.getLatLng() }, sticker: this.sticker, }); stopEditing = () => { this.element.className = 'sticker-container inactive'; }; startEditing = () => { this.element.className = 'sticker-container'; }; }