mirror of
https://github.com/muerwre/orchidmap-front.git
synced 2025-04-25 11:06:40 +07:00
svg buttons (initial)
removed styled-components gradient paths
This commit is contained in:
parent
245b559e2d
commit
7229a48297
22 changed files with 853 additions and 89 deletions
19
src/components/Fills.jsx
Normal file
19
src/components/Fills.jsx
Normal file
|
@ -0,0 +1,19 @@
|
|||
import React from 'react';
|
||||
|
||||
export const Fills = () => (
|
||||
<svg>
|
||||
<defs>
|
||||
<linearGradient id="activeButtonGradient" x1="-20%" x2="50%" y1="0%" y2="140%">
|
||||
<stop offset="0%" stopColor="#55ddff" />
|
||||
<stop offset="100%" stopColor="#7137c8" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
|
||||
<defs>
|
||||
<linearGradient id="activePathGradient" x1="-20%" x2="50%" y1="0%" y2="140%">
|
||||
<stop offset="0%" stopColor="#ff9900" />
|
||||
<stop offset="100%" stopColor="#ff3344" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
)
|
9
src/components/Icon.jsx
Normal file
9
src/components/Icon.jsx
Normal file
|
@ -0,0 +1,9 @@
|
|||
import React from 'react';
|
||||
import sprite from '$sprites/icon.svg';
|
||||
|
||||
export const Icon = ({ icon, size = 32 }) => (
|
||||
<svg width={size} height={size} viewBox="0 0 32 32" preserveAspectRatio="midXmidY meet">
|
||||
<use xlinkHref={`${sprite}#${icon}`} x={0} y={0} />
|
||||
</svg>
|
||||
);
|
||||
|
49
src/components/panels/EditorPanel.jsx
Normal file
49
src/components/panels/EditorPanel.jsx
Normal file
|
@ -0,0 +1,49 @@
|
|||
import React from 'react';
|
||||
import { MODES } from '$constants/modes';
|
||||
import classnames from 'classnames';
|
||||
|
||||
import { Icon } from '$components/Icon';
|
||||
|
||||
export class EditorPanel extends React.PureComponent {
|
||||
startPolyMode = () => this.props.editor.changeMode(MODES.POLY);
|
||||
|
||||
startStickerMode = () => this.props.editor.changeMode(MODES.STICKERS);
|
||||
|
||||
startRouterMode = () => this.props.editor.changeMode(MODES.ROUTER);
|
||||
|
||||
startShotterMode = () => this.props.editor.changeMode(MODES.SHOTTER);
|
||||
|
||||
render() {
|
||||
const { mode } = this.props;
|
||||
|
||||
return (
|
||||
<div id="control-screen">
|
||||
<button
|
||||
className={classnames({ active: mode === MODES.ROUTER })}
|
||||
onClick={this.startRouterMode}
|
||||
>
|
||||
<Icon icon="icon-router" />
|
||||
</button>
|
||||
<button
|
||||
className={classnames({ active: mode === MODES.POLY })}
|
||||
onClick={this.startPolyMode}
|
||||
>
|
||||
<Icon icon="icon-poly" />
|
||||
</button>
|
||||
<button
|
||||
className={classnames({ active: mode === MODES.STICKERS })}
|
||||
onClick={this.startStickerMode}
|
||||
>
|
||||
<Icon icon="icon-sticker" />
|
||||
</button>
|
||||
|
||||
<button
|
||||
className={classnames({ active: mode === MODES.SHOTTER })}
|
||||
onClick={this.startShotterMode}
|
||||
>
|
||||
<Icon icon="icon-shooter" />
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
};
|
|
@ -2,5 +2,6 @@ export const MODES = {
|
|||
POLY: 'POLY',
|
||||
STICKERS: 'STICKERS',
|
||||
ROUTER: 'ROUTER',
|
||||
SHOTTER: 'SHOTTER',
|
||||
NONE: 'NONE',
|
||||
};
|
||||
|
|
|
@ -1,54 +1,43 @@
|
|||
import React from 'react';
|
||||
|
||||
import { Editor } from '$modules/Editor';
|
||||
|
||||
import { MapScreen } from '$styles/mapScreen';
|
||||
import { ControlsScreen } from '$styles/controlsScreen';
|
||||
import { MODES } from '$constants/modes';
|
||||
import { EditorPanel } from '$components/panels/EditorPanel';
|
||||
import { Fills } from '$components/Fills';
|
||||
|
||||
export class App extends React.Component {
|
||||
state = {
|
||||
mode: 'none',
|
||||
editor: null,
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
const container = 'map';
|
||||
const { mode } = this.state;
|
||||
|
||||
this.editor = new Editor({
|
||||
const editor = new Editor({
|
||||
container,
|
||||
mode,
|
||||
setMode: this.setMode,
|
||||
});
|
||||
|
||||
this.setState({ editor })
|
||||
}
|
||||
|
||||
setMode = mode => {
|
||||
this.setState({ mode });
|
||||
};
|
||||
|
||||
startPolyMode = () => this.editor.changeMode(MODES.POLY);
|
||||
|
||||
startStickerMode = () => this.editor.changeMode(MODES.STICKERS);
|
||||
|
||||
startRouterMode = () => this.editor.changeMode(MODES.ROUTER);
|
||||
|
||||
render() {
|
||||
const { mode } = this.state;
|
||||
const {
|
||||
state: { mode, editor },
|
||||
} = this;
|
||||
|
||||
|
||||
return (
|
||||
<div>
|
||||
<MapScreen />
|
||||
<ControlsScreen>
|
||||
<button onClick={this.startPolyMode}>
|
||||
{mode === MODES.POLY && '-->'}{MODES.POLY}
|
||||
</button>
|
||||
<button onClick={this.startStickerMode}>
|
||||
{mode === MODES.STICKERS && '-->'}{MODES.STICKERS}
|
||||
</button>
|
||||
<button onClick={this.startRouterMode}>
|
||||
{mode === MODES.ROUTER && '-->'}{MODES.ROUTER}
|
||||
</button>
|
||||
</ControlsScreen>
|
||||
<Fills />
|
||||
<div id="map" />
|
||||
<EditorPanel editor={editor} mode={mode} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<meta name="viewport" content="initial-scale=1, maximum-scale=0.8">
|
||||
<link rel="icon" href="favicon.png?d" type="image/png" />
|
||||
|
||||
<title>@MAP</title>
|
||||
<title>@ORCHID</title>
|
||||
|
||||
<link rel="shortcut icon" href="/favicon.png?wd" type="image/png">
|
||||
<meta property="og:image" content="/misc/vk_preview.png" />
|
||||
|
|
|
@ -3,6 +3,9 @@ import ReactDOM from 'react-dom';
|
|||
|
||||
import { App } from '$containers/App';
|
||||
|
||||
import '$styles/map.less';
|
||||
import '$styles/controls.less';
|
||||
|
||||
export const Index = () => (
|
||||
<App />
|
||||
);
|
||||
|
|
|
@ -3,6 +3,7 @@ import { Poly } from '$modules/Poly';
|
|||
import { MODES } from '$constants/modes';
|
||||
import { Stickers } from '$modules/Stickers';
|
||||
import { Router } from '$modules/Router';
|
||||
import { Shotter } from '$modules/Shotter';
|
||||
|
||||
export class Editor {
|
||||
constructor({
|
||||
|
@ -14,9 +15,10 @@ export class Editor {
|
|||
|
||||
const { lockMapClicks, routerMoveStart, map: { map } } = this;
|
||||
|
||||
this.poly = new Poly({ map, routerMoveStart });
|
||||
this.poly = new Poly({ map, routerMoveStart, lockMapClicks });
|
||||
this.stickers = new Stickers({ map, lockMapClicks });
|
||||
this.router = new Router({ map, lockMapClicks });
|
||||
this.shotter = new Shotter({ map });
|
||||
|
||||
this.setMode = setMode;
|
||||
this.mode = mode;
|
||||
|
@ -28,6 +30,9 @@ export class Editor {
|
|||
},
|
||||
[MODES.ROUTER]: {
|
||||
start: this.routerSetStart,
|
||||
},
|
||||
[MODES.SHOTTER]: {
|
||||
start: this.shotter.makeShot,
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import L from 'leaflet';
|
||||
import { map, tileLayer } from 'leaflet';
|
||||
import { providers } from '$constants/providers';
|
||||
|
||||
import 'leaflet/dist/leaflet.css';
|
||||
|
@ -6,9 +6,9 @@ import 'leaflet-editable';
|
|||
|
||||
export class Map {
|
||||
constructor({ container }) {
|
||||
this.map = L.map(container, { editable: true }).setView([55.0153275, 82.9071235], 13);
|
||||
this.map = map(container, { editable: true }).setView([55.0153275, 82.9071235], 13);
|
||||
|
||||
this.tileLayer = L.tileLayer(providers.default, {
|
||||
this.tileLayer = tileLayer(providers.default, {
|
||||
attribution: 'Независимое Велосообщество',
|
||||
maxNativeZoom: 18,
|
||||
maxZoom: 18,
|
||||
|
|
|
@ -1,19 +1,21 @@
|
|||
import L from "leaflet";
|
||||
import { polyline } from "leaflet";
|
||||
|
||||
const polyStyle = { color: '#ff3333', weight: '5' };
|
||||
const polyStyle = { color: 'url(#activePathGradient)', weight: '5' };
|
||||
|
||||
export class Poly {
|
||||
constructor({ map, routerMoveStart }) {
|
||||
this.poly = L.polyline([], polyStyle);
|
||||
constructor({ map, routerMoveStart, lockMapClicks }) {
|
||||
this.poly = polyline([], polyStyle);
|
||||
this.latlngs = [];
|
||||
this.poly.addTo(map);
|
||||
this.map = map;
|
||||
|
||||
this.routerMoveStart = routerMoveStart;
|
||||
this.lockMapClicks = lockMapClicks;
|
||||
this.bindEvents();
|
||||
}
|
||||
|
||||
updateMarks = () => {
|
||||
console.log('upd');
|
||||
const coords = this.poly.toGeoJSON().geometry.coordinates;
|
||||
this.latlngs = (coords && coords.length && coords.map(([lng, lat]) => ({ lng, lat }))) || [];
|
||||
|
||||
|
@ -28,6 +30,8 @@ export class Poly {
|
|||
this.map.editTools.addEventListener('editable:vertex:deleted', this.updateMarks);
|
||||
this.map.editTools.addEventListener('editable:vertex:new', this.updateMarks);
|
||||
|
||||
this.map.editTools.addEventListener('editable:vertex:dragstart', this.lockMap);
|
||||
|
||||
// После удаления точки - продолжить рисование
|
||||
this.map.editTools.addEventListener('editable:vertex:deleted', this.continueForward);
|
||||
//
|
||||
|
@ -70,4 +74,8 @@ export class Poly {
|
|||
if (!this.poly.editor) return;
|
||||
this.poly.editor.continueForward();
|
||||
};
|
||||
|
||||
lockMap = () => {
|
||||
this.lockMapClicks(true);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import L from 'leaflet';
|
||||
import 'leaflet-routing-machine';
|
||||
import Routing from 'leaflet-routing-machine/src/index';
|
||||
import { CONFIG } from '$config';
|
||||
import { DomMarker } from '$utils/DomMarker';
|
||||
|
||||
export class Router {
|
||||
constructor({ map, lockMapClicks }) {
|
||||
const routeLine = r => L.Routing.line(r, {
|
||||
const routeLine = r => Routing.line(r, {
|
||||
styles: [
|
||||
{ color: 'white', opacity: 0.8, weight: 6 },
|
||||
{ color: '#4597d0', opacity: 1, weight: 4, dashArray: '15,10' }
|
||||
|
@ -13,7 +13,7 @@ export class Router {
|
|||
addWaypoints: true,
|
||||
}).on('linetouched', this.lockPropagations);
|
||||
|
||||
this.router = L.Routing.control({
|
||||
this.router = Routing.control({
|
||||
serviceUrl: CONFIG.OSRM_URL,
|
||||
profile: 'bike',
|
||||
fitSelectedRoutes: false,
|
||||
|
@ -22,7 +22,7 @@ export class Router {
|
|||
styles: [{ color: '#4597d0', opacity: 1, weight: 3 }]
|
||||
},
|
||||
show: false,
|
||||
plan: L.Routing.plan([], {
|
||||
plan: Routing.plan([], {
|
||||
createMarker: (i, wp) => L.marker(wp.latLng, {
|
||||
draggable: true,
|
||||
icon: this.createWaypointMarker(),
|
||||
|
@ -38,9 +38,7 @@ export class Router {
|
|||
this.waypoints = [];
|
||||
this.lockMapClicks = lockMapClicks;
|
||||
|
||||
console.log('router', this.router);
|
||||
// this.router._line.on('mousedown', console.log);
|
||||
console.log('map', map);
|
||||
}
|
||||
//
|
||||
pushWaypointOnClick = ({ latlng: { lat, lng } }) => {
|
||||
|
@ -83,9 +81,7 @@ export class Router {
|
|||
};
|
||||
//
|
||||
unlockPropagations = e => {
|
||||
console.log('unlock');
|
||||
if (e && e.preventPropagations) {
|
||||
console.log('stop');
|
||||
e.preventDefault();
|
||||
e.preventPropagations();
|
||||
}
|
||||
|
|
66
src/modules/Shotter.js
Normal file
66
src/modules/Shotter.js
Normal file
|
@ -0,0 +1,66 @@
|
|||
import axios from 'axios';
|
||||
|
||||
export class Shotter {
|
||||
constructor({ map }) {
|
||||
this.tiles = [];
|
||||
this.tilesLoaded = 0;
|
||||
this.map = map;
|
||||
}
|
||||
|
||||
latLngToTile = latlng => {
|
||||
const z = this.map.getZoom();
|
||||
const x = parseInt(Math.floor(((latlng.lng + 180) / 360) * (1 << z)), 10);
|
||||
const y = parseInt(Math.floor((1 - (Math.log(Math.tan((latlng.lat * Math.PI) / 180)
|
||||
+ 1 / Math.cos((latlng.lat * Math.PI) / 180)) / Math.PI)) / 2 * (1 << z)), 10);
|
||||
return { x, y, z };
|
||||
};
|
||||
|
||||
tileToLatLng = point => {
|
||||
const z = this.map.getZoom();
|
||||
const lng = (((point.x / (2 ** z)) * 360) - 180);
|
||||
|
||||
const n = Math.PI - ((2 * Math.PI * point.y) / (2 ** z));
|
||||
const lat = (180 / Math.PI * Math.atan(0.5 * (Math.exp(n) - Math.exp(-n))));
|
||||
|
||||
return { lat, lng };
|
||||
};
|
||||
|
||||
getTilePlacement() {
|
||||
const { innerHeight, innerWidth } = window;
|
||||
const { _southWest, _northEast } = this.map.getBounds();
|
||||
|
||||
const sw = this.latLngToTile(_southWest);
|
||||
const ne = this.latLngToTile(_northEast);
|
||||
|
||||
const zsw = this.tileToLatLng(sw);
|
||||
const zne = this.tileToLatLng(ne);
|
||||
|
||||
const rsw = this.map.latLngToContainerPoint(zsw);
|
||||
const msw = this.map.latLngToContainerPoint(_southWest);
|
||||
|
||||
return {
|
||||
min_x: sw.x,
|
||||
min_y: ne.y,
|
||||
max_x: ne.x,
|
||||
max_y: sw.y,
|
||||
sh_x: (rsw.x - msw.x),
|
||||
sh_y: ((innerHeight + rsw.y) - msw.y),
|
||||
size: 256,
|
||||
width: innerWidth,
|
||||
height: innerHeight,
|
||||
zoom: this.map.getZoom(),
|
||||
provider: 'dgis',
|
||||
};
|
||||
}
|
||||
|
||||
makeShot = () => {
|
||||
// console.log('shot', this.getTilePlacement());
|
||||
const placement = this.getTilePlacement();
|
||||
|
||||
axios.get('http://alpha-map.vault48.org/engine/composerOrchid.php', {
|
||||
params: { placement, mode: 'test' }
|
||||
})
|
||||
.then(console.log)
|
||||
.catch(console.warn);
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
import L from 'leaflet';
|
||||
import { marker } from 'leaflet';
|
||||
import 'leaflet-editable';
|
||||
|
||||
import { DomMarker } from '$utils/DomMarker';
|
||||
|
@ -28,12 +28,12 @@ export class Sticker {
|
|||
this.element.appendChild(this.stickerImage);
|
||||
this.element.appendChild(this.stickerDelete);
|
||||
|
||||
const marker = new DomMarker({
|
||||
const mark = new DomMarker({
|
||||
element: this.element,
|
||||
className: 'sticker-container',
|
||||
});
|
||||
|
||||
this.sticker = L.marker(latlng, { icon: marker });
|
||||
this.sticker = marker(latlng, { icon: mark });
|
||||
|
||||
this.setAngle(this.angle);
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import L from 'leaflet';
|
||||
import { layerGroup } from 'leaflet';
|
||||
import { Sticker } from '$modules/Sticker';
|
||||
|
||||
export class Stickers {
|
||||
constructor({ map, lockMapClicks }) {
|
||||
this.map = map;
|
||||
this.layer = L.layerGroup();
|
||||
this.layer = layerGroup();
|
||||
|
||||
this.lockMapClicks = lockMapClicks;
|
||||
this.stickers = [];
|
||||
|
|
38
src/sprites/icon.svg
Normal file
38
src/sprites/icon.svg
Normal file
|
@ -0,0 +1,38 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="64" height="64">
|
||||
<defs>
|
||||
<g id="icon-router">
|
||||
<rect x="0" y="0" width="32" height="32" fill="none" stroke="none" />
|
||||
<g transform="translate(-680 -226)">
|
||||
<path d="M693.047 229.072c-2.105-.003-3.587 1.238-4.3 2.354a6.454 6.454 0 0 0-.888 2.226l-.02.123v12.137h3v-11.814c.01-.045.098-.531.434-1.057.352-.549.722-.97 1.77-.969 1.073.001 1.547.446 1.945.983.367.493.47.894.49.966v12.45s-.003 1.326.624 2.723c.626 1.396 2.196 3.019 4.627 3.068 2.45.05 4.063-1.603 4.689-3.022.626-1.418.621-2.77.621-2.77v-10.949h-3v10.913s-.032.84-.365 1.595c-.334.756-.61 1.259-1.885 1.233-1.295-.027-1.617-.557-1.95-1.297a4.623 4.623 0 0 1-.36-1.526v-12.873l-.045-.177s-.256-1.071-1.035-2.121c-.78-1.05-2.273-2.193-4.352-2.196z" stroke="none" />
|
||||
<path d="M704.367 229.072a2.795 2.795 0 0 0-2.781 2.782 2.795 2.795 0 0 0 2.781 2.78 2.795 2.795 0 0 0 2.781-2.78 2.795 2.795 0 0 0-2.78-2.782zm0 1.782c.563 0 .998.437.998 1a.984.984 0 0 1-.998.998c-.562 0-1-.436-1-.998 0-.563.438-1 1-1z" stroke="none" />
|
||||
<path d="M689.34 246.7a2.796 2.796 0 0 0-2.781 2.782 2.795 2.795 0 0 0 2.78 2.782 2.796 2.796 0 0 0 2.784-2.782 2.798 2.798 0 0 0-2.783-2.783zm0 1.782c.562 0 1 .438 1 1a.986.986 0 0 1-1 .998.984.984 0 0 1-.998-.998c0-.562.435-1 .998-1z" stroke="none" />
|
||||
|
||||
<path d="M693.047 229.072c-2.105-.003-3.587 1.238-4.3 2.354a6.454 6.454 0 0 0-.888 2.226l-.02.123v12.137h3v-11.814c.01-.045.098-.531.434-1.057.352-.549.722-.97 1.77-.969 1.073.001 1.547.446 1.945.983.367.493.47.894.49.966v12.45s-.003 1.326.624 2.723c.626 1.396 2.196 3.019 4.627 3.068 2.45.05 4.063-1.603 4.689-3.022.626-1.418.621-2.77.621-2.77v-10.949h-3v10.913s-.032.84-.365 1.595c-.334.756-.61 1.259-1.885 1.233-1.295-.027-1.617-.557-1.95-1.297a4.623 4.623 0 0 1-.36-1.526v-12.873l-.045-.177s-.256-1.071-1.035-2.121c-.78-1.05-2.273-2.193-4.352-2.196z" stroke="none" />
|
||||
<path d="M704.367 229.072a2.795 2.795 0 0 0-2.781 2.782 2.795 2.795 0 0 0 2.781 2.78 2.795 2.795 0 0 0 2.781-2.78 2.795 2.795 0 0 0-2.78-2.782zm0 1.782c.563 0 .998.437.998 1a.984.984 0 0 1-.998.998c-.562 0-1-.436-1-.998 0-.563.438-1 1-1z" id="path1471" overflow="visible" stroke="none" />
|
||||
<path d="M689.34 246.7a2.796 2.796 0 0 0-2.781 2.782 2.795 2.795 0 0 0 2.78 2.782 2.796 2.796 0 0 0 2.784-2.782 2.798 2.798 0 0 0-2.783-2.783zm0 1.782c.562 0 1 .438 1 1a.986.986 0 0 1-1 .998.984.984 0 0 1-.998-.998c0-.562.435-1 .998-1z" id="path1473" overflow="visible" stroke="none" />
|
||||
</g>
|
||||
</g>
|
||||
|
||||
<g id="icon-sticker">
|
||||
<rect x="0" y="0" width="32" height="32" fill="none" stroke="none" />
|
||||
<g transform="translate(-680 -285)">
|
||||
<path d="M690.764 306.811l5.71 7.913 5.014-7.694z" stroke="none" />
|
||||
<path transform="matrix(.88332 0 0 .88132 81.246 35.954)" d="M702.328 307.792l-6.02-.026-6.02.026-2.986-5.226-3.033-5.2 3.033-5.2 2.987-5.227 6.02.026 6.02-.026 2.986 5.226 3.033 5.2-3.033 5.2z" fill="none" stroke-width="3"/>
|
||||
</g>
|
||||
</g>
|
||||
|
||||
<g id="icon-poly">
|
||||
<rect x="0" y="0" width="32" height="32" fill="none" stroke="none" />
|
||||
<g transform="translate(-680 -228.5)">
|
||||
<path d="m 696.0049,231.55643 c -1.64501,0 -3,1.35499 -3,3 0,0.29055 0.0541,0.5674 0.13281,0.83399 l -5.8164,4.13281 c -0.21393,-0.0492 -0.43422,-0.082 -0.66211,-0.082 -1.64501,0 -3,1.35499 -3,3 0,1.645 1.35499,3 3,3 1.64501,0 3,-1.355 3,-3 0,-0.28194 -0.0527,-0.54906 -0.12695,-0.8086 l 3.34179,-2.375 c -0.51555,3.11587 -1.37236,8.36742 -2.01172,11.50391 -1.61147,0.0399 -2.92773,1.37189 -2.92773,2.99219 0,1.645 1.35499,3 3,3 1.64501,0 3,-1.355 3,-3 0,-0.21144 -0.0259,-0.41564 -0.0684,-0.61524 l 9.0918,-6.7539 -0.91016,3.81445 c -1.24757,0.36364 -2.17578,1.50927 -2.17578,2.86719 0,1.645 1.35499,3 3,3 1.64501,0 3,-1.355 3,-3 0,-0.83682 -0.35298,-1.5941 -0.91406,-2.14063 l 1.58398,-6.64257 c 1.55126,-0.10673 2.79883,-1.4042 2.79883,-2.98047 0,-1.64501 -1.35499,-3 -3,-3 -1.64501,0 -3,1.35499 -3,3 0,0.32848 0.0664,0.64062 0.16602,0.9375 l -9.36915,6.96093 c 0.84795,-4.50286 1.78434,-9.8666 2.09766,-11.66796 1.53745,-0.12126 2.76953,-1.41034 2.76953,-2.97657 0,-1.64501 -1.35499,-3 -3,-3 z m 0,2 c 0.56413,0 1,0.43587 1,1 0,0.56413 -0.43587,1 -1,1 -0.56413,0 -1,-0.43587 -1,-1 0,-0.56413 0.43587,-1 1,-1 z m 10.33594,6.7461 c 0.56413,0 1,0.43587 1,1 0,0.56413 -0.43587,1 -1,1 -0.56413,0 -1,-0.43587 -1,-1 0,-0.56413 0.43587,-1 1,-1 z m -19.68164,1.13867 c 0.56413,0 1,0.43587 1,1 0,0.56412 -0.43587,0.99999 -1,1 -0.56413,0 -1,-0.43588 -1,-1 0,-0.56413 0.43587,-1 1,-1 z m 16.13477,10.64062 0.58984,0.14063 c 0.28935,0.1726 0.48828,0.47288 0.48828,0.84375 0,0.56412 -0.43587,0.99999 -1,1 -0.56413,0 -1,-0.43588 -1,-1 0,-0.53619 0.39847,-0.94406 0.92188,-0.98438 z m -11.85938,0.67188 c 0.56413,0 1,0.43587 1,1 0,0.56412 -0.43587,0.99999 -1,1 -0.56413,0 -1,-0.43588 -1,-1 0,-0.56413 0.43587,-1 1,-1 z" stroke="none" />
|
||||
<path d="m 696.00488,230.26355 c -1.64501,0 -3,1.35499 -3,3 0,0.29055 0.0541,0.5674 0.13281,0.83399 l -5.8164,4.13281 c -0.21393,-0.0492 -0.43422,-0.082 -0.66211,-0.082 -1.64501,0 -3,1.35499 -3,3 0,1.645 1.35499,3 3,3 1.64501,0 3,-1.355 3,-3 0,-0.28194 -0.0527,-0.54906 -0.12695,-0.8086 l 3.34179,-2.375 c -0.51555,3.11587 -1.37236,8.36742 -2.01172,11.50391 -1.61147,0.0399 -2.92773,1.37189 -2.92773,2.99219 0,1.645 1.35499,3 3,3 1.64501,0 3,-1.355 3,-3 0,-0.21144 -0.0258,-0.41564 -0.0684,-0.61524 l 9.0918,-6.7539 -0.91016,3.81445 c -1.24757,0.36364 -2.17578,1.50927 -2.17578,2.86719 0,1.645 1.35499,3 3,3 1.64501,0 3,-1.355 3,-3 0,-0.83682 -0.35298,-1.5941 -0.91406,-2.14063 l 1.58398,-6.64257 c 1.55126,-0.10673 2.79883,-1.4042 2.79883,-2.98047 0,-1.64501 -1.35499,-3 -3,-3 -1.64501,0 -3,1.35499 -3,3 0,0.32848 0.0664,0.64062 0.16602,0.9375 l -9.36915,6.96093 c 0.84795,-4.50286 1.78434,-9.8666 2.09766,-11.66796 1.53745,-0.12126 2.76953,-1.41034 2.76953,-2.97657 0,-1.64501 -1.35499,-3 -3,-3 z m 0,2 c 0.56413,0 1,0.43587 1,1 0,0.56413 -0.43587,1 -1,1 -0.56413,0 -1,-0.43587 -1,-1 0,-0.56413 0.43587,-1 1,-1 z m 10.33594,6.7461 c 0.56413,0 1,0.43587 1,1 0,0.56413 -0.43587,1 -1,1 -0.56413,0 -1,-0.43587 -1,-1 0,-0.56413 0.43587,-1 1,-1 z m -19.68164,1.13867 c 0.56413,0 1,0.43587 1,1 0,0.56412 -0.43587,0.99999 -1,1 -0.56413,0 -1,-0.43588 -1,-1 0,-0.56413 0.43587,-1 1,-1 z m 16.13477,10.64062 0.58984,0.14063 c 0.28935,0.1726 0.48828,0.47288 0.48828,0.84375 0,0.56412 -0.43587,0.99999 -1,1 -0.56413,0 -1,-0.43588 -1,-1 0,-0.53619 0.39847,-0.94406 0.92188,-0.98438 z m -11.85938,0.67188 c 0.56413,0 1,0.43587 1,1 0,0.56412 -0.43587,0.99999 -1,1 -0.56413,0 -1,-0.43588 -1,-1 0,-0.56413 0.43587,-1 1,-1 z" stroke="none" />
|
||||
</g>
|
||||
</g>
|
||||
|
||||
<g id="icon-shooter">
|
||||
<rect x="0" y="0" width="32" height="32" fill="none" stroke="none" />
|
||||
<g transform="translate(18 6)">
|
||||
<path d="m0 0l-4.391.054c-1.418.531-2.34 1.756-3.176 3.102h-5.178c-.68.317-1.351.655-1.455 2.584v11.49c.17 1.001.58 1.765 1.455 2.06h22.537c.746-.044 1.288-.426 1.68-1.06v-13.517c-.185-1.643-.916-1.65-1.68-1.557h-6.62c-.326-1.26-1.91-2.247-3.172-3.156zm-2.122 5.289c3.227 0 5.87 2.626 5.87 5.846s-2.643 5.845-5.87 5.845c-3.227 0-5.869-2.626-5.869-5.845 0-3.22 2.642-5.846 5.87-5.846zm0 1.998a3.844 3.844 0 0 0-3.869 3.848 3.842 3.842 0 0 0 3.87 3.845 3.84 3.84 0 0 0 3.866-3.845 3.842 3.842 0 0 0-3.867-3.848z" />
|
||||
</g>
|
||||
</defs>
|
||||
</svg>
|
After Width: | Height: | Size: 7.4 KiB |
35
src/styles/controls.less
Normal file
35
src/styles/controls.less
Normal file
|
@ -0,0 +1,35 @@
|
|||
|
||||
#control-screen {
|
||||
position: fixed;
|
||||
right: 10px;
|
||||
bottom: 0px;
|
||||
height: 48px;
|
||||
min-width: 120px;
|
||||
background: #333333;
|
||||
z-index: 2;
|
||||
color: white;
|
||||
border-radius: 4px 4px 0 0;
|
||||
padding: 0 4px 0 4px;
|
||||
|
||||
button {
|
||||
border: none;
|
||||
background: transparent;
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
padding: 8px;
|
||||
outline: none;
|
||||
cursor: pointer;
|
||||
|
||||
&.active {
|
||||
svg {
|
||||
fill: url(#activeButtonGradient);
|
||||
stroke: url(#activeButtonGradient);
|
||||
}
|
||||
}
|
||||
|
||||
svg {
|
||||
fill: white;
|
||||
stroke: white;
|
||||
}
|
||||
}
|
||||
}
|
176
src/styles/map.less
Normal file
176
src/styles/map.less
Normal file
|
@ -0,0 +1,176 @@
|
|||
#map {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
left: 0;
|
||||
top: 0;
|
||||
|
||||
cursor: crosshair;
|
||||
}
|
||||
|
||||
.leaflet-vertex-icon, .leaflet-middle-icon {
|
||||
border-radius: 10px;
|
||||
opacity :1;
|
||||
border: none;
|
||||
width: 16px !important;
|
||||
height: 16px !important;margin-left:-8px !important;margin-top:-8px !important;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.leaflet-vertex-icon::after, .leaflet-middle-icon::after {
|
||||
content: ' ';
|
||||
position:absolute;top:4px;left:4px;width:8px;height:8px;
|
||||
background:white;border-radius: 8px;transform:scale(1);
|
||||
transition:transform 150ms;
|
||||
}
|
||||
|
||||
.leaflet-vertex-icon:hover, .leaflet-middle-icon:hover {
|
||||
opacity: 1 !important;
|
||||
}
|
||||
|
||||
.leaflet-vertex-icon:hover::after, .leaflet-middle-icon:hover::after,
|
||||
.leaflet-vertex-icon:active::after, .leaflet-middle-icon:active::after {
|
||||
transform: scale(2);
|
||||
box-shadow: #999 0 0 5px 2px;
|
||||
}
|
||||
|
||||
.leaflet-control-container .leaflet-routing-container-hide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.router-waypoint {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
margin-left: -20px;
|
||||
margin-top: -20px;
|
||||
outline: none;
|
||||
z-index: 10001;
|
||||
|
||||
&:after {
|
||||
content: ' ';
|
||||
display: block;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 0 0 2px #4597d0;
|
||||
margin-left: 10px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.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, transform 500ms;
|
||||
transform: scale(0);
|
||||
}
|
||||
|
||||
&:hover, &:active {
|
||||
.sticker-delete {
|
||||
transform: scale(1);
|
||||
pointer-events: all;
|
||||
}
|
||||
|
||||
&:before {
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.sticker-label {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
position: absolute;
|
||||
background: white;
|
||||
border-radius: 32px;
|
||||
left: 0;
|
||||
top: 0;
|
||||
outline: none;
|
||||
|
||||
&:after {
|
||||
content: ' ';
|
||||
box-shadow: 0 0 0 1px #ff3344;
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
left: -16px;
|
||||
top: -16px;
|
||||
position: absolute;
|
||||
border-radius: 40px;
|
||||
pointer-events: none;
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
}
|
||||
|
||||
.leaflet-control-container .leaflet-routing-container-hide {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.router-waypoint {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
margin-left: -20px;
|
||||
margin-top: -20px;
|
||||
outline: none;
|
||||
z-index: 10001;
|
||||
|
||||
&:after {
|
||||
content: ' ';
|
||||
display: block;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 0 0 2px #4597d0;
|
||||
margin-left: 10px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
import L from 'leaflet';
|
||||
import { DivIcon } from 'leaflet';
|
||||
|
||||
export const DomMarker = L.DivIcon.extend({
|
||||
export const DomMarker = DivIcon.extend({
|
||||
initialize: function (options) {
|
||||
this.options = options;
|
||||
},
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue