From 58eefd5670c61cf6573c9ad8f573fe45cb05067e Mon Sep 17 00:00:00 2001 From: Fedor Katurov Date: Mon, 30 Dec 2019 15:07:59 +0700 Subject: [PATCH] stickers stops dragging --- src/containers/map/Map/index.tsx | 22 +- src/containers/map/Route/index.tsx | 48 ++-- src/containers/map/Sticker/index.tsx | 118 ++++++++++ src/containers/map/Stickers/index.tsx | 39 ++++ src/containers/map/TileLayer/index.tsx | 8 +- src/modules/InteractivePoly.ts | 311 ++++++++++++++----------- src/modules/Sticker.tsx | 3 + src/redux/map/index.ts | 4 + src/redux/map/selectors.ts | 7 +- src/redux/user/sagas.ts | 3 +- 10 files changed, 388 insertions(+), 175 deletions(-) create mode 100644 src/containers/map/Sticker/index.tsx create mode 100644 src/containers/map/Stickers/index.tsx diff --git a/src/containers/map/Map/index.tsx b/src/containers/map/Map/index.tsx index 2f76a56..65b8a3e 100644 --- a/src/containers/map/Map/index.tsx +++ b/src/containers/map/Map/index.tsx @@ -2,15 +2,18 @@ import { Map as MapInterface, map } from "leaflet"; import * as React from "react"; import { createPortal } from "react-dom"; import { MapContext } from "$utils/context.ts"; -import { TileLayer } from "$containers/map/TileLayer"; -import { Route } from "$containers/map/Route"; -import { selectMapProvider, selectMapRoute } from "$redux/map/selectors"; +import { selectMapProvider, selectMapRoute, selectMapStickers } from "$redux/map/selectors"; import { connect } from "react-redux"; import * as MAP_ACTIONS from "$redux/map/actions"; +import { Route } from "$containers/map/Route"; +import { TileLayer } from "$containers/map/TileLayer"; +import { Stickers } from "$containers/map/Stickers"; + const mapStateToProps = state => ({ provider: selectMapProvider(state), - route: selectMapRoute(state) + route: selectMapRoute(state), + stickers: selectMapStickers(state), }); const mapDispatchToProps = { @@ -21,7 +24,7 @@ type IProps = React.HTMLAttributes & ReturnType & typeof mapDispatchToProps & {}; -const MapUnconnected: React.FC = ({ provider, route, mapSetRoute }) => { +const MapUnconnected: React.FC = ({ provider, route, mapSetRoute, stickers }) => { const ref = React.useRef(null); const [maps, setMaps] = React.useState(null); @@ -31,12 +34,13 @@ const MapUnconnected: React.FC = ({ provider, route, mapSetRoute }) => { setMaps(map(ref.current).setView([55.0153275, 82.9071235], 13)); }, [ref]); + // console.log('RERENDER!'); + return createPortal(
- - - - + + +
, document.getElementById("canvas") ); diff --git a/src/containers/map/Route/index.tsx b/src/containers/map/Route/index.tsx index 4eb2936..a39bf6b 100644 --- a/src/containers/map/Route/index.tsx +++ b/src/containers/map/Route/index.tsx @@ -10,21 +10,40 @@ import { IMapRoute, ILatLng } from "../../../redux/map/types"; import { MapContext } from "$utils/context"; import { InteractivePoly } from "$modules/InteractivePoly"; import { isMobile } from "$utils/window"; -import { LatLng } from "leaflet"; +import { LatLng, Map } from "leaflet"; interface IProps { + map: Map; route: IMapRoute; is_editing: boolean; mapSetRoute: (latlngs: ILatLng[]) => void; } -const Route: FC = memo(({ route, is_editing, mapSetRoute }) => { +const Route: FC = memo(({ route, is_editing, mapSetRoute, map }) => { const [layer, setLayer] = useState(null); - const map = useContext(MapContext); + + useEffect(() => { + if (!map) return; + + setLayer( + new InteractivePoly([], { + color: "url(#activePathGradient)", + weight: 6, + maxMarkers: isMobile() ? 20 : 100, + smoothFactor: 3, + }) + .addTo(map) + // .on("distancechange", console.log) + // .on("allvertexhide", console.log) + // .on("allvertexshow", console.log) + ); + }, [map]); + const onRouteChanged = useCallback( ({ latlngs }) => { - // mapSetRoute(latlngs) + // console.log('THIS!'); + mapSetRoute(latlngs) }, [mapSetRoute] ); @@ -37,28 +56,11 @@ const Route: FC = memo(({ route, is_editing, mapSetRoute }) => { return () => layer.off("latlngschange", onRouteChanged); }, [layer, onRouteChanged]); - useEffect(() => { - if (!map) return; - - setLayer( - new InteractivePoly([], { - color: "url(#activePathGradient)", - weight: 6, - maxMarkers: isMobile() ? 20 : 100, - smoothFactor: 3, - updateself: false, - }) - .addTo(map) - .on("distancechange", console.log) - .on("allvertexhide", console.log) - .on("allvertexshow", console.log) - // .on("latlngschange", console.log) - ); - }, [map]); - useEffect(() => { if (!layer) return; + console.log('route use effect!') + const points = (route && route.length > 0 && route) || []; layer.setPoints(points as LatLng[]); // TODO: refactor this diff --git a/src/containers/map/Sticker/index.tsx b/src/containers/map/Sticker/index.tsx new file mode 100644 index 0000000..c487bd3 --- /dev/null +++ b/src/containers/map/Sticker/index.tsx @@ -0,0 +1,118 @@ +import * as React from "react"; +import { Map, marker, Marker } from "leaflet"; +import { IStickerDump, Sticker as StickerComponent } from "$modules/Sticker"; +import { STICKERS } from "$constants/stickers"; +import { StickerDesc } from "$components/StickerDesc"; +import classNames from "classnames"; +import { DomMarker } from "$utils/DomMarker"; +import { createPortal } from "react-dom"; + +interface IProps { + map: Map; + sticker: IStickerDump; +} + +const preventPropagation = (e): void => { + if (!e || !e.stopPropagation) return; + + e.stopPropagation(); + e.preventDefault(); +}; + +const getX = e => + e.touches && e.touches.length > 0 + ? { pageX: e.touches[0].pageX, pageY: e.touches[0].pageY } + : { pageX: e.pageX, pageY: e.pageY }; + +const Sticker: React.FC = ({ map, sticker }) => { + const [layer, setLayer] = React.useState(null); + const [dragging, setDragging] = React.useState(false); + + const stickerArrow = React.useRef(null); + const stickerImage = React.useRef(null); + + const onDragStart = React.useCallback(() => { + layer.dragging.disable(); + map.dragging.disable(); + + setDragging(true); + }, [setDragging, layer, map]); + + const onDragStop = React.useCallback(() => { + layer.dragging.enable(); + map.dragging.enable(); + + setDragging(false); + }, [setDragging, layer, map]); + + const onDrag = React.useCallback(event => { + // event.stopPrapagation(); + // console.log("drag") + }, []); + + const onDelete = console.log; + const setText = console.log; + + const direction = React.useMemo(() => "left", [sticker.angle]); + + const element = React.useMemo(() => document.createElement("div"), []); + + React.useEffect(() => { + if (dragging) { + document.addEventListener("mousemove", onDrag); + document.addEventListener("mouseUp", onDragStop); + } + + return () => document.removeEventListener("mousemove", onDrag); + }, [dragging, onDrag]); + + React.useEffect(() => { + if (!map) return; + + const icon = new DomMarker({ + element, + className: "sticker-container" + }); + + const item = marker(sticker.latlng, { icon, draggable: true }).addTo(map); + + setLayer(item); + + return () => item.removeFrom(map); + }, [element, map, sticker]); + + return createPortal( + +
+
+ + +
+ +
+
+ , + element + ); +}; + +export { Sticker }; diff --git a/src/containers/map/Stickers/index.tsx b/src/containers/map/Stickers/index.tsx new file mode 100644 index 0000000..7185d9f --- /dev/null +++ b/src/containers/map/Stickers/index.tsx @@ -0,0 +1,39 @@ +import * as React from "react"; +import { IStickerDump } from "$modules/Sticker"; +import { Layer, FeatureGroup, Map } from "leaflet"; +import { MapContext } from "$utils/context"; +import { Sticker } from "$containers/map/Sticker"; + +interface IProps { + stickers: IStickerDump[]; + is_editing: boolean; + map: Map; +} + +// const { FC, useContext, useState, useEffect } = React; + +const Stickers: React.FC = React.memo(({ stickers, is_editing, map }) => { + const [layer, setLayer] = React.useState(null); + + React.useEffect(() => { + if (!map) return; + + setLayer(new FeatureGroup().addTo(map)); + }, [map]); + + return ( +
+ {layer && + stickers.map((sticker, index) => ( + + ))} +
+ ); + // return null; +}); + +export { Stickers }; diff --git a/src/containers/map/TileLayer/index.tsx b/src/containers/map/TileLayer/index.tsx index fdddeb6..6466e6e 100644 --- a/src/containers/map/TileLayer/index.tsx +++ b/src/containers/map/TileLayer/index.tsx @@ -1,16 +1,16 @@ import * as React from "react"; import { MapContext, TileContext } from "../../../utils/context"; -import { TileLayer as TileLayerInterface, tileLayer } from "leaflet"; +import { TileLayer as TileLayerInterface, tileLayer, Map } from "leaflet"; import { DEFAULT_PROVIDER, PROVIDERS } from "$constants/providers"; import { IMapReducer } from "$redux/map"; type IProps = React.HTMLAttributes & { provider: IMapReducer['provider'], + map: Map, }; -const TileLayer: React.FC = ({ children, provider }) => { +const TileLayer: React.FC = React.memo(({ children, provider, map }) => { const [layer, setLayer] = React.useState(null); - const map = React.useContext(MapContext); React.useEffect(() => { if (!map) return; @@ -35,6 +35,6 @@ const TileLayer: React.FC = ({ children, provider }) => { }, [layer, provider]); return {children}; -}; +}); export { TileLayer }; diff --git a/src/modules/InteractivePoly.ts b/src/modules/InteractivePoly.ts index 4f5c324..33822a9 100644 --- a/src/modules/InteractivePoly.ts +++ b/src/modules/InteractivePoly.ts @@ -15,23 +15,29 @@ import { LatLng, LeafletMouseEvent, latLng, - LatLngLiteral, -} from 'leaflet'; + LatLngLiteral +} from "leaflet"; import { distKm, distToSegment, getPolyLength, pointInArea } from "$utils/geom"; interface InteractivePolylineOptions extends PolylineOptions { - maxMarkers?: number, - constraintsStyle?: PolylineOptions, - kmMarksEnabled?: boolean, - kmMarksStep?: number, + maxMarkers?: number; + constraintsStyle?: PolylineOptions; + kmMarksEnabled?: boolean; + kmMarksStep?: number; } export class InteractivePoly extends Polyline { - constructor(latlngs: LatLngExpression[] | LatLngExpression[][], options?: InteractivePolylineOptions) { + constructor( + latlngs: LatLngExpression[] | LatLngExpression[][], + options?: InteractivePolylineOptions + ) { super(latlngs, options); - this.constraintsStyle = { ...this.constraintsStyle, ...options.constraintsStyle }; + this.constraintsStyle = { + ...this.constraintsStyle, + ...options.constraintsStyle + }; this.maxMarkers = options.maxMarkers || this.maxMarkers; this.constrLine = new Polyline([], this.constraintsStyle); @@ -43,36 +49,41 @@ export class InteractivePoly extends Polyline { this.touchHinter.setLatLngs(latlngs); }; - setPoints = (latlngs: LatLng[]) => { + setPoints = (latlngs: LatLng[], emitEvent = false) => { this.setLatLngs(latlngs); this.recreateMarkers(); this.recalcDistance(); this.touchHinter.setLatLngs(latlngs); - this.fire('latlngschange', { latlngs }); + + if (emitEvent) { + this.fire("latlngschange", { latlngs }); + } }; - createHintMarker = (latlng: LatLng): Marker => marker(latlng, { - draggable: false, - icon: divIcon({ - className: 'leaflet-vertex-drag-helper', - iconSize: [11, 11], - iconAnchor: [6, 6] - }) - }); + createHintMarker = (latlng: LatLng): Marker => + marker(latlng, { + draggable: false, + icon: divIcon({ + className: "leaflet-vertex-drag-helper", + iconSize: [11, 11], + iconAnchor: [6, 6] + }) + }); - createMarker = (latlng: LatLng): Marker => marker(latlng, { - draggable: true, - icon: divIcon({ - className: 'leaflet-vertex-icon', - iconSize: [11, 11], - iconAnchor: [6, 6] + createMarker = (latlng: LatLng): Marker => + marker(latlng, { + draggable: true, + icon: divIcon({ + className: "leaflet-vertex-icon", + iconSize: [11, 11], + iconAnchor: [6, 6] + }) }) - }) - .on('contextmenu', this.dropMarker) - .on('drag', this.onMarkerDrag) - .on('dragstart', this.onMarkerDragStart) - .on('dragend', this.onMarkerDragEnd) - .addTo(this.markerLayer); + .on("contextmenu", this.dropMarker) + .on("drag", this.onMarkerDrag) + .on("dragstart", this.onMarkerDragStart) + .on("dragend", this.onMarkerDragEnd) + .addTo(this.markerLayer); recreateMarkers = () => { this.clearAllMarkers(); @@ -99,14 +110,14 @@ export class InteractivePoly extends Polyline { if (this._map.hasLayer(this.markerLayer)) return; this._map.addLayer(this.markerLayer); - this.fire('allvertexshow'); + this.fire("allvertexshow"); }; hideAllMarkers = (): void => { if (!this._map.hasLayer(this.markerLayer)) return; this._map.removeLayer(this.markerLayer); - this.fire('allvertexhide'); + this.fire("allvertexhide"); }; showVisibleMarkers = (): void => { @@ -115,15 +126,19 @@ export class InteractivePoly extends Polyline { const northEast = this._map.getBounds().getNorthEast(); const southWest = this._map.getBounds().getSouthWest(); - const { visible, hidden } = this.markers.reduce((obj, marker) => { - const { lat, lng } = marker.getLatLng(); - const is_hidden = (lat > northEast.lat || lng > northEast.lng || lat < southWest.lat || lng < southWest.lng); + const { visible, hidden } = this.markers.reduce( + (obj, marker) => { + const { lat, lng } = marker.getLatLng(); + const is_hidden = + lat > northEast.lat || + lng > northEast.lng || + lat < southWest.lat || + lng < southWest.lng; - return is_hidden - ? { ...obj, hidden: [...obj.hidden, marker] } - : { ...obj, visible: [...obj.visible, marker] } - - }, + return is_hidden + ? { ...obj, hidden: [...obj.hidden, marker] } + : { ...obj, visible: [...obj.visible, marker] }; + }, { visible: [], hidden: [] } ); @@ -136,7 +151,8 @@ export class InteractivePoly extends Polyline { }); hidden.forEach(marker => { - if (this.markerLayer.hasLayer(marker)) this.markerLayer.removeLayer(marker); + if (this.markerLayer.hasLayer(marker)) + this.markerLayer.removeLayer(marker); }); }; @@ -147,7 +163,7 @@ export class InteractivePoly extends Polyline { this.stopDragHinting(); this.stopDrawing(); this.touchHinter.removeFrom(this._map); - this.fire('editordisable'); + this.fire("editordisable"); }, enable: () => { this.is_editing = true; @@ -155,16 +171,16 @@ export class InteractivePoly extends Polyline { this.startDragHinting(); this.touchHinter.addTo(this._map); - this.fire('editorenable'); + this.fire("editorenable"); }, continue: () => { this.is_drawing = true; - this.drawing_direction = 'forward'; + this.drawing_direction = "forward"; this.startDrawing(); }, prepend: () => { this.is_drawing = true; - this.drawing_direction = 'backward'; + this.drawing_direction = "backward"; this.startDrawing(); } }; @@ -174,7 +190,8 @@ export class InteractivePoly extends Polyline { }; hideDragHint = (): void => { - if (this._map.hasLayer(this.hintMarker)) this._map.removeLayer(this.hintMarker); + if (this._map.hasLayer(this.hintMarker)) + this._map.removeLayer(this.hintMarker); }; showDragHint = (): void => { @@ -182,17 +199,17 @@ export class InteractivePoly extends Polyline { }; startDragHinting = (): void => { - this.touchHinter.on('mousemove', this.moveDragHint); - this.touchHinter.on('mousedown', this.startDragHintMove); - this.touchHinter.on('mouseover', this.showDragHint); - this.touchHinter.on('mouseout', this.hideDragHint); + this.touchHinter.on("mousemove", this.moveDragHint); + this.touchHinter.on("mousedown", this.startDragHintMove); + this.touchHinter.on("mouseover", this.showDragHint); + this.touchHinter.on("mouseout", this.hideDragHint); }; stopDragHinting = (): void => { - this.touchHinter.off('mousemove', this.moveDragHint); - this.touchHinter.off('mousedown', this.startDragHintMove); - this.touchHinter.off('mouseover', this.showDragHint); - this.touchHinter.off('mouseout', this.hideDragHint); + this.touchHinter.off("mousemove", this.moveDragHint); + this.touchHinter.off("mousedown", this.startDragHintMove); + this.touchHinter.off("mouseover", this.showDragHint); + this.touchHinter.off("mouseout", this.hideDragHint); }; startDragHintMove = (event: LeafletMouseEvent): void => { @@ -216,9 +233,9 @@ export class InteractivePoly extends Polyline { this.is_dragging = true; - this._map.on('mousemove', this.dragHintMove); - this._map.on('mouseup', this.dragHintAddMarker); - this._map.on('mouseout', this.stopDragHintMove); + this._map.on("mousemove", this.dragHintMove); + this._map.on("mouseup", this.dragHintAddMarker); + this._map.on("mouseout", this.stopDragHintMove); }; stopDragHintMove = (): void => { @@ -226,23 +243,28 @@ export class InteractivePoly extends Polyline { this.constrLine.removeFrom(this._map); - this._map.off('mousemove', this.dragHintMove); - this._map.off('mouseup', this.dragHintAddMarker); - this._map.off('mouseout', this.stopDragHintMove); + this._map.off("mousemove", this.dragHintMove); + this._map.off("mouseup", this.dragHintAddMarker); + this._map.off("mouseout", this.stopDragHintMove); if (this.is_drawing) this.startDrawing(); - setTimeout(() => { this.is_dragging = false; }, 0); + setTimeout(() => { + this.is_dragging = false; + }, 0); }; dragHintAddMarker = ({ latlng }: LeafletMouseEvent): void => { this.dragHintChangeDistance(this.hint_prev_marker, latlng); - this.markers.splice((this.hint_prev_marker + 1), 0, this.createMarker(latlng)); + this.markers.splice( + this.hint_prev_marker + 1, + 0, + this.createMarker(latlng) + ); this.insertLatLng(latlng, this.hint_prev_marker + 1); this.hideDragHint(); this.stopDragHintMove(); - }; dragHintChangeDistance = (index: number, current: LatLngLiteral): void => { @@ -251,28 +273,30 @@ export class InteractivePoly extends Polyline { const initial_distance = distKm(prev.getLatLng(), next.getLatLng()); - const current_distance = ( + const current_distance = ((prev && distKm(prev.getLatLng(), current)) || 0) + - ((next && distKm(next.getLatLng(), current)) || 0) - ); + ((next && distKm(next.getLatLng(), current)) || 0); - this.distance += (current_distance - initial_distance); + this.distance += current_distance - initial_distance; - this.fire('distancechange', { distance: this.distance }); + this.fire("distancechange", { distance: this.distance }); }; dragHintFindNearest = (latlng: LatLng): any => { const latlngs = this.getLatLngs() as LatLng[]; - const neighbours = latlngs.filter((current, index) => { - const next = latlngs[index + 1] as LatLng; + const neighbours = latlngs + .filter((current, index) => { + const next = latlngs[index + 1] as LatLng; - return (next && pointInArea(current, next, latlng)); - }) + return next && pointInArea(current, next, latlng); + }) .map(el => latlngs.indexOf(el)) - .sort((a, b) => ( - distToSegment(latlngs[a], latlngs[a + 1], latlng) - distToSegment(latlngs[b], latlngs[b + 1], latlng) - )); + .sort( + (a, b) => + distToSegment(latlngs[a], latlngs[a + 1], latlng) - + distToSegment(latlngs[b], latlngs[b + 1], latlng) + ); return neighbours.length > 0 ? neighbours[0] : -1; }; @@ -284,22 +308,30 @@ export class InteractivePoly extends Polyline { this.setConstraints([ this.markers[this.hint_prev_marker].getLatLng(), event.latlng, - this.markers[this.hint_prev_marker + 1].getLatLng(), + this.markers[this.hint_prev_marker + 1].getLatLng() ]); }; - onMarkerDrag = ({ target }: { target: Marker}) => { + onMarkerDrag = ({ target }: { target: Marker }) => { const coords = new Array(0) - .concat((this.vertex_index > 0 && this.markers[this.vertex_index - 1].getLatLng()) || []) + .concat( + (this.vertex_index > 0 && + this.markers[this.vertex_index - 1].getLatLng()) || + [] + ) .concat(target.getLatLng()) - .concat((this.vertex_index < (this.markers.length - 1) && this.markers[this.vertex_index + 1].getLatLng()) || []); + .concat( + (this.vertex_index < this.markers.length - 1 && + this.markers[this.vertex_index + 1].getLatLng()) || + [] + ); this.setConstraints(coords); - this.fire('vertexdrag', { index: this.vertex_index, vertex: target }); + this.fire("vertexdrag", { index: this.vertex_index, vertex: target }); }; - onMarkerDragStart = ({ target }: { target: Marker}) => { + onMarkerDragStart = ({ target }: { target: Marker }) => { if (this.is_drawing) { this.stopDrawing(); this.is_drawing = true; @@ -312,12 +344,16 @@ export class InteractivePoly extends Polyline { this.is_dragging = true; this.constrLine.addTo(this._map); - this.fire('vertexdragstart', { index: this.vertex_index, vertex: target }); + this.fire("vertexdragstart", { index: this.vertex_index, vertex: target }); }; - onMarkerDragEnd = ({ target }: { target: Marker}): void => { + onMarkerDragEnd = ({ target }: { target: Marker }): void => { const latlngs = this.getLatLngs() as LatLngLiteral[]; - this.markerDragChangeDistance(this.vertex_index, latlngs[this.vertex_index], target.getLatLng()); + this.markerDragChangeDistance( + this.vertex_index, + latlngs[this.vertex_index], + target.getLatLng() + ); this.replaceLatlng(target.getLatLng(), this.vertex_index); @@ -328,40 +364,43 @@ export class InteractivePoly extends Polyline { if (this.is_drawing) this.startDrawing(); - this.fire('vertexdragend', { index: this.vertex_index, vertex: target }); + this.fire("vertexdragend", { index: this.vertex_index, vertex: target }); }; - markerDragChangeDistance = (index: number, initial: LatLngLiteral, current: LatLngLiteral): void => { + markerDragChangeDistance = ( + index: number, + initial: LatLngLiteral, + current: LatLngLiteral + ): void => { const prev = index > 0 ? this.markers[index - 1] : null; - const next = index <= (this.markers.length + 1) ? this.markers[index + 1] : null; + const next = + index <= this.markers.length + 1 ? this.markers[index + 1] : null; - const initial_distance = ( + const initial_distance = ((prev && distKm(prev.getLatLng(), initial)) || 0) + - ((next && distKm(next.getLatLng(), initial)) || 0) - ); + ((next && distKm(next.getLatLng(), initial)) || 0); - const current_distance = ( + const current_distance = ((prev && distKm(prev.getLatLng(), current)) || 0) + - ((next && distKm(next.getLatLng(), current)) || 0) - ); + ((next && distKm(next.getLatLng(), current)) || 0); - this.distance += (current_distance - initial_distance); + this.distance += current_distance - initial_distance; - this.fire('distancechange', { distance: this.distance }); + this.fire("distancechange", { distance: this.distance }); }; startDrawing = (): void => { this.is_drawing = true; this.setConstraints([]); this.constrLine.addTo(this._map); - this._map.on('mousemove', this.onDrawingMove); - this._map.on('click', this.onDrawingClick); + this._map.on("mousemove", this.onDrawingMove); + this._map.on("click", this.onDrawingClick); }; stopDrawing = (): void => { this.constrLine.removeFrom(this._map); - this._map.off('mousemove', this.onDrawingMove); - this._map.off('click', this.onDrawingClick); + this._map.off("mousemove", this.onDrawingMove); + this._map.off("click", this.onDrawingClick); this.is_drawing = false; }; @@ -371,11 +410,13 @@ export class InteractivePoly extends Polyline { return; } - if (!this._map.hasLayer(this.constrLine)) this._map.addLayer(this.constrLine); + if (!this._map.hasLayer(this.constrLine)) + this._map.addLayer(this.constrLine); - const marker = this.drawing_direction === 'forward' - ? this.markers[this.markers.length - 1] - : this.markers[0]; + const marker = + this.drawing_direction === "forward" + ? this.markers[this.markers.length - 1] + : this.markers[0]; this.setConstraints([latlng, marker.getLatLng()]); }; @@ -391,7 +432,7 @@ export class InteractivePoly extends Polyline { this.drawingChangeDistance(latlng); - if (this.drawing_direction === 'forward') { + if (this.drawing_direction === "forward") { latlngs.push(latlng); this.markers.push(this.createMarker(latlng)); } else { @@ -400,7 +441,7 @@ export class InteractivePoly extends Polyline { } this.setLatLngs(latlngs); - this.fire('latlngschange', { latlngs }); + this.fire("latlngschange", { latlngs }); this.showVisibleMarkers(); this.startDrawing(); }; @@ -410,30 +451,31 @@ export class InteractivePoly extends Polyline { if (latlngs.length < 1) { this.distance = 0; - this.fire('distancechange', { distance: this.distance }); + this.fire("distancechange", { distance: this.distance }); return; } - const point = this.drawing_direction === 'forward' - ? latlngs[latlngs.length - 1] - : latlngs[0]; + const point = + this.drawing_direction === "forward" + ? latlngs[latlngs.length - 1] + : latlngs[0]; this.distance += distKm(point, latlng); - this.fire('distancechange', { distance: this.distance }); + this.fire("distancechange", { distance: this.distance }); }; replaceLatlng = (latlng: LatLng, index: number): void => { const latlngs = this.getLatLngs() as LatLngLiteral[]; latlngs.splice(index, 1, latlng); this.setLatLngs(latlngs); - this.fire('latlngschange', { latlngs }); + this.fire("latlngschange", { latlngs }); }; insertLatLng = (latlng, index): void => { const latlngs = this.getLatLngs(); latlngs.splice(index, 0, latlng); this.setLatLngs(latlngs); - this.fire('latlngschange', { latlngs }); + this.fire("latlngschange", { latlngs }); }; setConstraints = (coords: LatLng[]) => { @@ -444,7 +486,7 @@ export class InteractivePoly extends Polyline { const index = this.markers.indexOf(target); const latlngs = this.getLatLngs(); - if (typeof index === 'undefined' || latlngs.length <= 2) return; + if (typeof index === "undefined" || latlngs.length <= 2) return; this.dropMarkerDistanceChange(index); this._map.removeLayer(this.markers[index]); @@ -452,7 +494,7 @@ export class InteractivePoly extends Polyline { latlngs.splice(index, 1); this.setLatLngs(latlngs); - this.fire('latlngschange', { latlngs }); + this.fire("latlngschange", { latlngs }); }; dropMarkerDistanceChange = (index: number): void => { @@ -460,43 +502,42 @@ export class InteractivePoly extends Polyline { const prev = index > 0 ? latlngs[index - 1] : null; const current = latlngs[index]; - const next = index <= (latlngs.length + 1) ? latlngs[index + 1] : null; + const next = index <= latlngs.length + 1 ? latlngs[index + 1] : null; - const initial_distance = ( + const initial_distance = ((prev && distKm(prev, current)) || 0) + - ((next && distKm(next, current)) || 0) - ); + ((next && distKm(next, current)) || 0); const current_distance = (prev && next && distKm(prev, next)) || 0; - this.distance += (current_distance - initial_distance); + this.distance += current_distance - initial_distance; - this.fire('distancechange', { distance: this.distance }); + this.fire("distancechange", { distance: this.distance }); }; recalcDistance = () => { const latlngs = this.getLatLngs() as LatLngLiteral[]; this.distance = getPolyLength(latlngs); - this.fire('distancechange', { distance: this.distance }); + this.fire("distancechange", { distance: this.distance }); }; markers: Marker[] = []; - maxMarkers: InteractivePolylineOptions['maxMarkers'] = 2; + maxMarkers: InteractivePolylineOptions["maxMarkers"] = 2; markerLayer: LayerGroup = new LayerGroup(); - constraintsStyle: InteractivePolylineOptions['constraintsStyle'] = { + constraintsStyle: InteractivePolylineOptions["constraintsStyle"] = { weight: 6, - color: 'red', - dashArray: '10, 12', + color: "red", + dashArray: "10, 12", opacity: 0.5, - interactive: false, + interactive: false }; touchHinter: Polyline = new Polyline([], { weight: 24, smoothFactor: 3, - className: 'touch-hinter-poly' + className: "touch-hinter-poly" }); hintMarker: Marker = this.createHintMarker(latLng({ lat: 0, lng: 0 })); @@ -507,28 +548,28 @@ export class InteractivePoly extends Polyline { is_dragging: boolean = false; is_drawing: boolean = false; - drawing_direction: 'forward' | 'backward' = 'forward'; + drawing_direction: "forward" | "backward" = "forward"; vertex_index?: number = null; hint_prev_marker: number = null; distance: number = 0; } -InteractivePoly.addInitHook(function () { - this.once('add', (event) => { +InteractivePoly.addInitHook(function() { + this.once("add", event => { if (event.target instanceof InteractivePoly) { this.map = event.target._map; - this.map.on('touch', console.log); + this.map.on("touch", console.log); this.markerLayer.addTo(event.target._map); this.hintMarker.addTo(event.target._map); this.constrLine.addTo(event.target._map); this.touchHinter.addTo(event.target._map); - this.map.on('moveend', this.updateMarkers); + this.map.on("moveend", this.updateMarkers); - this.on('latlngschange', this.updateTouchHinter); + this.on("latlngschange", this.updateTouchHinter); if (window.innerWidth < 768) { this.touchHinter.setStyle({ weight: 32 }); @@ -536,14 +577,14 @@ InteractivePoly.addInitHook(function () { } }); - this.once('remove', (event) => { + this.once("remove", event => { if (event.target instanceof InteractivePoly) { this.markerLayer.removeFrom(this._map); this.hintMarker.removeFrom(this._map); this.constrLine.removeFrom(this._map); this.touchHinter.removeFrom(this._map); - this.map.off('moveend', this.updateMarkers); + this.map.off("moveend", this.updateMarkers); } }); }); diff --git a/src/modules/Sticker.tsx b/src/modules/Sticker.tsx index ea2bb2b..ef33651 100644 --- a/src/modules/Sticker.tsx +++ b/src/modules/Sticker.tsx @@ -56,6 +56,7 @@ export class Sticker { this.deleteSticker = deleteSticker; this.lockMapClicks = lockMapClicks; this.editor = editor; + this.element = document.createElement('div'); ReactDOM.render( @@ -178,6 +179,8 @@ export class Sticker { }; setAngle = (angle: Props['angle']): void => { + if (!this.stickerImage) return; + const direction = getLabelDirection(angle); if (direction !== this.direction) { diff --git a/src/redux/map/index.ts b/src/redux/map/index.ts index ba5bb99..35d8920 100644 --- a/src/redux/map/index.ts +++ b/src/redux/map/index.ts @@ -2,14 +2,18 @@ import { createReducer } from 'reduxsauce'; import { MAP_HANDLERS } from './handlers'; import { DEFAULT_PROVIDER } from '$constants/providers'; import { IMapRoute } from './types'; +import { IStickerDump } from '$modules/Sticker'; export interface IMapReducer { provider: string; route: IMapRoute; + stickers: IStickerDump[] } export const MAP_INITIAL_STATE = { provider: DEFAULT_PROVIDER, + route: [], + stickers: [], } export const map = createReducer(MAP_INITIAL_STATE, MAP_HANDLERS) \ No newline at end of file diff --git a/src/redux/map/selectors.ts b/src/redux/map/selectors.ts index 5b169a8..8a1675b 100644 --- a/src/redux/map/selectors.ts +++ b/src/redux/map/selectors.ts @@ -1,2 +1,5 @@ -export const selectMapProvider = state => state.map.provider; -export const selectMapRoute= state => state.map.route; \ No newline at end of file +import { IState } from "$redux/store"; + +export const selectMapProvider = (state: IState) => state.map.provider; +export const selectMapRoute= (state: IState) => state.map.route; +export const selectMapStickers = (state: IState) => state.map.stickers; \ No newline at end of file diff --git a/src/redux/user/sagas.ts b/src/redux/user/sagas.ts index 9ba905b..d148e84 100644 --- a/src/redux/user/sagas.ts +++ b/src/redux/user/sagas.ts @@ -157,8 +157,6 @@ function* loadMapSaga(path) { data: { route, error, random_url } }: Unwrap = yield call(getStoredMap, { name: path }); - console.log({ route }); - if (route && !error) { yield editor.clearAll(); yield editor.setData(route); @@ -172,6 +170,7 @@ function* loadMapSaga(path) { yield put(mapSet({ provider: route.provider, route: route.route, + stickers: route.stickers, })) return { route, random_url };