mirror of
https://github.com/muerwre/orchidmap-front.git
synced 2025-04-25 19:16:41 +07:00
sticker panel with ability to choose
This commit is contained in:
parent
40a11297c0
commit
f2c9cc4abc
10 changed files with 140 additions and 64 deletions
|
@ -2,14 +2,19 @@ import React from 'react';
|
||||||
import { MODES } from '$constants/modes';
|
import { MODES } from '$constants/modes';
|
||||||
|
|
||||||
import { RouterHelper } from '$components/router/RouterHelper';
|
import { RouterHelper } from '$components/router/RouterHelper';
|
||||||
|
import { StickersHelper } from '$components/stickers/StickersHelper';
|
||||||
|
|
||||||
export const EditorDialog = ({ mode, routerPoints, editor }) => {
|
export const EditorDialog = ({ mode, routerPoints, editor, activeSticker }) => {
|
||||||
const showDialog = (mode === MODES.ROUTER);
|
const showDialog = (
|
||||||
|
mode === MODES.ROUTER
|
||||||
|
|| (mode === MODES.STICKERS && !activeSticker)
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
showDialog &&
|
showDialog &&
|
||||||
<div id="control-dialog">
|
<div id="control-dialog">
|
||||||
{ mode === MODES.ROUTER && <RouterHelper routerPoints={routerPoints} editor={editor} /> }
|
{ mode === MODES.ROUTER && <RouterHelper routerPoints={routerPoints} editor={editor} /> }
|
||||||
|
{ mode === MODES.STICKERS && <StickersHelper editor={editor} /> }
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -18,7 +18,7 @@ export class EditorPanel extends React.PureComponent {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
mode, routerPoints, editor, totalDistance, estimateTime
|
mode, routerPoints, editor, totalDistance, estimateTime, activeSticker
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -27,6 +27,7 @@ export class EditorPanel extends React.PureComponent {
|
||||||
<EditorDialog
|
<EditorDialog
|
||||||
mode={mode}
|
mode={mode}
|
||||||
routerPoints={routerPoints}
|
routerPoints={routerPoints}
|
||||||
|
activeSticker={activeSticker}
|
||||||
editor={editor}
|
editor={editor}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
@ -44,14 +45,14 @@ export class EditorPanel extends React.PureComponent {
|
||||||
<div className="control-dist">
|
<div className="control-dist">
|
||||||
{(totalDistance > 0)
|
{(totalDistance > 0)
|
||||||
?
|
?
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
{totalDistance} км
|
{totalDistance} км
|
||||||
<Icon icon="icon-cycle" size={32} />
|
<Icon icon="icon-cycle" size={32} />
|
||||||
{
|
{
|
||||||
(estimateTime > 0) && (estimateTime > 0) && <span>{toHours(estimateTime)}</span>
|
(estimateTime > 0) && (estimateTime > 0) && <span>{toHours(estimateTime)}</span>
|
||||||
}
|
}
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
: <div onClick={() => editor.changeMode(MODES.ROUTER)}>Начнать рисовать</div>
|
: <div onClick={() => editor.changeMode(MODES.ROUTER)}>Начать рисовать</div>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
22
src/components/stickers/StickersHelper.jsx
Normal file
22
src/components/stickers/StickersHelper.jsx
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import { stickers } from '$constants/stickers';
|
||||||
|
import sprite from '$sprites/stickers.svg';
|
||||||
|
|
||||||
|
export class StickersHelper extends React.Component {
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div className="stickers-helper">
|
||||||
|
{
|
||||||
|
stickers.map(sticker => (
|
||||||
|
<div className="sticker-preview" key={sticker}>
|
||||||
|
<svg width={48} height={48} viewBox="0 0 64 64" onClick={() => this.props.editor.setSticker(sticker)}>
|
||||||
|
<use xlinkHref={`${sprite}#sticker-${sticker}`} x="0" y="0" width="64" height="64" />
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
))
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,43 +1,45 @@
|
||||||
// Стикеры
|
// Стикеры
|
||||||
import L from "leaflet";
|
// import L from "leaflet";
|
||||||
|
|
||||||
export const stickers = {
|
export const stickers = ['green', 'basic', 'green-small'];
|
||||||
'objects': {},
|
|
||||||
'layers': L.layerGroup(),
|
|
||||||
'savedata': {},
|
|
||||||
'layer_to_object': {},
|
|
||||||
'src': [
|
|
||||||
{off: 5, title: 'Александр 3', title_long: 'Парк Городское Начало', latlng: [55.01275, 82.92368]},
|
|
||||||
{off: 9, title: 'пл.Калинина', title_long: "пл.Калинина", latlng: [55.06019, 82.91316]},
|
|
||||||
{off: 4, title: 'Мост', title_long: 'Мост', latlng: [55.00511, 82.93073]},
|
|
||||||
{off: 7, title: 'Икея', title_long: "Парковка ТЦ Мега", latlng: [54.96494, 82.93138]},
|
|
||||||
{off: 8, title: 'Бугринка', title_long: "Та самая коса\n(культовое место Усталых Педалек)", latlng: [54.97626, 82.95703]},
|
|
||||||
{off: 10, title: 'ГПНТБ', title_long: "ГПНТБ", latlng: [55.01665, 82.94629]}, // второй ряд
|
|
||||||
{off: 18, title: 'Оперный', title_long: "Оперный театр", latlng: [55.03027, 82.92292]},
|
|
||||||
{off: 1, title: 'Лес', title_long: 'Берёзовая роща', latlng: [55.04572, 82.95]}, // первый ряд
|
|
||||||
{off: 19, title: 'Пусто', title_long: "Пока что пусто 1"},
|
|
||||||
{off: 20, title: 'Пусто', title_long: "Пока что пусто 2"}, // третий ряд
|
|
||||||
|
|
||||||
{off: 2, title: 'Трасса', title_long: 'Дорога'},
|
// export const _stickers = {
|
||||||
{off: 3, title: 'Курочка', title_long: 'Курочка'},
|
// 'objects': {},
|
||||||
{off: 6, title: 'Палатка', title_long: 'Палаточный лагерь'},
|
// 'layers': L.layerGroup(),
|
||||||
{off: 11, title: 'Фастфуд', title_long: "Двухколёсное ожирение"},
|
// 'savedata': {},
|
||||||
{off: 12, title: 'Пивко', title_long: "В Питере - пить!"},
|
// 'layer_to_object': {},
|
||||||
{off: 13, title: 'Шаварма', title_long: "Вкусная шаурма"},
|
// 'src': [
|
||||||
{off: 14, title: 'Камни', title_long: "Кааааммммуушшшки"},
|
// {off: 5, title: 'Александр 3', title_long: 'Парк Городское Начало', latlng: [55.01275, 82.92368]},
|
||||||
{off: 15, title: 'Болото', title_long: "Пошла ты,\nтрясина грёбаная!"},
|
// {off: 9, title: 'пл.Калинина', title_long: "пл.Калинина", latlng: [55.06019, 82.91316]},
|
||||||
{off: 16, title: 'Роджер', title_long: "Может не надо?"},
|
// {off: 4, title: 'Мост', title_long: 'Мост', latlng: [55.00511, 82.93073]},
|
||||||
{off: 17, title: 'Какашка', title_long: "Нехорошее место"},
|
// {off: 7, title: 'Икея', title_long: "Парковка ТЦ Мега", latlng: [54.96494, 82.93138]},
|
||||||
|
// {off: 8, title: 'Бугринка', title_long: "Та самая коса\n(культовое место Усталых Педалек)", latlng: [54.97626, 82.95703]},
|
||||||
{off: 21, title: 'Старт', title_long: "Старт здесь"},
|
// {off: 10, title: 'ГПНТБ', title_long: "ГПНТБ", latlng: [55.01665, 82.94629]}, // второй ряд
|
||||||
{off: 22, title: '1', title_long: "Первая точка"},
|
// {off: 18, title: 'Оперный', title_long: "Оперный театр", latlng: [55.03027, 82.92292]},
|
||||||
{off: 23, title: '2', title_long: "Вторая точка"},
|
// {off: 1, title: 'Лес', title_long: 'Берёзовая роща', latlng: [55.04572, 82.95]}, // первый ряд
|
||||||
{off: 24, title: '3', title_long: "Третья точка"},
|
// {off: 19, title: 'Пусто', title_long: "Пока что пусто 1"},
|
||||||
{off: 25, title: '4', title_long: "Четвёртая точка"},
|
// {off: 20, title: 'Пусто', title_long: "Пока что пусто 2"}, // третий ряд
|
||||||
{off: 26, title: '5', title_long: "Пятая точка"},
|
//
|
||||||
{off: 27, title: '7', title_long: "Шестая точка"},
|
// {off: 2, title: 'Трасса', title_long: 'Дорога'},
|
||||||
{off: 28, title: 'Финиш', title_long: "Финиш здесь"},
|
// {off: 3, title: 'Курочка', title_long: 'Курочка'},
|
||||||
{off: 29, title: 'Осторожно!', title_long: "Осторожно!"},
|
// {off: 6, title: 'Палатка', title_long: 'Палаточный лагерь'},
|
||||||
{off: 30, title: 'Вопрос', title_long: "Что тут?"}
|
// {off: 11, title: 'Фастфуд', title_long: "Двухколёсное ожирение"},
|
||||||
]
|
// {off: 12, title: 'Пивко', title_long: "В Питере - пить!"},
|
||||||
};
|
// {off: 13, title: 'Шаварма', title_long: "Вкусная шаурма"},
|
||||||
|
// {off: 14, title: 'Камни', title_long: "Кааааммммуушшшки"},
|
||||||
|
// {off: 15, title: 'Болото', title_long: "Пошла ты,\nтрясина грёбаная!"},
|
||||||
|
// {off: 16, title: 'Роджер', title_long: "Может не надо?"},
|
||||||
|
// {off: 17, title: 'Какашка', title_long: "Нехорошее место"},
|
||||||
|
//
|
||||||
|
// {off: 21, title: 'Старт', title_long: "Старт здесь"},
|
||||||
|
// {off: 22, title: '1', title_long: "Первая точка"},
|
||||||
|
// {off: 23, title: '2', title_long: "Вторая точка"},
|
||||||
|
// {off: 24, title: '3', title_long: "Третья точка"},
|
||||||
|
// {off: 25, title: '4', title_long: "Четвёртая точка"},
|
||||||
|
// {off: 26, title: '5', title_long: "Пятая точка"},
|
||||||
|
// {off: 27, title: '7', title_long: "Шестая точка"},
|
||||||
|
// {off: 28, title: 'Финиш', title_long: "Финиш здесь"},
|
||||||
|
// {off: 29, title: 'Осторожно!', title_long: "Осторожно!"},
|
||||||
|
// {off: 30, title: 'Вопрос', title_long: "Что тут?"}
|
||||||
|
// ]
|
||||||
|
// };
|
||||||
|
|
|
@ -10,6 +10,7 @@ export class App extends React.Component {
|
||||||
routerPoints: 0,
|
routerPoints: 0,
|
||||||
totalDistance: 0,
|
totalDistance: 0,
|
||||||
estimateTime: 0,
|
estimateTime: 0,
|
||||||
|
activeSticker: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
setMode = mode => {
|
setMode = mode => {
|
||||||
|
@ -26,18 +27,25 @@ export class App extends React.Component {
|
||||||
this.setState({ totalDistance, estimateTime });
|
this.setState({ totalDistance, estimateTime });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
setActiveSticker = activeSticker => {
|
||||||
|
this.setState({ activeSticker });
|
||||||
|
};
|
||||||
|
|
||||||
editor = new Editor({
|
editor = new Editor({
|
||||||
container: 'map',
|
container: 'map',
|
||||||
mode: this.state.mode,
|
mode: this.state.mode,
|
||||||
setMode: this.setMode,
|
setMode: this.setMode,
|
||||||
setRouterPoints: this.setRouterPoints,
|
setRouterPoints: this.setRouterPoints,
|
||||||
setTotalDist: this.setTotalDist,
|
setTotalDist: this.setTotalDist,
|
||||||
|
setActiveSticker: this.setActiveSticker,
|
||||||
});
|
});
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
editor,
|
editor,
|
||||||
state: { mode, routerPoints, totalDistance, estimateTime },
|
state: {
|
||||||
|
mode, routerPoints, totalDistance, estimateTime, activeSticker
|
||||||
|
},
|
||||||
} = this;
|
} = this;
|
||||||
|
|
||||||
|
|
||||||
|
@ -50,6 +58,7 @@ export class App extends React.Component {
|
||||||
routerPoints={routerPoints}
|
routerPoints={routerPoints}
|
||||||
totalDistance={totalDistance}
|
totalDistance={totalDistance}
|
||||||
estimateTime={estimateTime}
|
estimateTime={estimateTime}
|
||||||
|
activeSticker={activeSticker}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -12,6 +12,7 @@ export class Editor {
|
||||||
setMode,
|
setMode,
|
||||||
setRouterPoints,
|
setRouterPoints,
|
||||||
setTotalDist,
|
setTotalDist,
|
||||||
|
setActiveSticker,
|
||||||
}) {
|
}) {
|
||||||
this.map = new Map({ container });
|
this.map = new Map({ container });
|
||||||
|
|
||||||
|
@ -19,7 +20,9 @@ export class Editor {
|
||||||
lockMapClicks, routerMoveStart, changeMode, pushPolyPoints, map: { map }
|
lockMapClicks, routerMoveStart, changeMode, pushPolyPoints, map: { map }
|
||||||
} = this;
|
} = this;
|
||||||
|
|
||||||
this.poly = new Poly({ map, routerMoveStart, lockMapClicks, setTotalDist });
|
this.poly = new Poly({
|
||||||
|
map, routerMoveStart, lockMapClicks, setTotalDist
|
||||||
|
});
|
||||||
this.stickers = new Stickers({ map, lockMapClicks });
|
this.stickers = new Stickers({ map, lockMapClicks });
|
||||||
this.router = new Router({
|
this.router = new Router({
|
||||||
map, lockMapClicks, setRouterPoints, changeMode, pushPolyPoints
|
map, lockMapClicks, setRouterPoints, changeMode, pushPolyPoints
|
||||||
|
@ -43,15 +46,26 @@ export class Editor {
|
||||||
};
|
};
|
||||||
|
|
||||||
this.clickHandlers = {
|
this.clickHandlers = {
|
||||||
[MODES.STICKERS]: this.stickers.createOnClick,
|
[MODES.STICKERS]: this.createStickerOnClick,
|
||||||
[MODES.ROUTER]: this.router.pushWaypointOnClick,
|
[MODES.ROUTER]: this.router.pushWaypointOnClick,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.activeSticker = null;
|
||||||
|
this.setActiveSticker = setActiveSticker;
|
||||||
|
|
||||||
map.addEventListener('mouseup', this.onClick);
|
map.addEventListener('mouseup', this.onClick);
|
||||||
map.addEventListener('dragstart', () => lockMapClicks(true));
|
map.addEventListener('dragstart', () => lockMapClicks(true));
|
||||||
map.addEventListener('dragstop', () => lockMapClicks(false));
|
map.addEventListener('dragstop', () => lockMapClicks(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
createStickerOnClick = (e) => {
|
||||||
|
if (!e || !e.latlng || !this.activeSticker) return;
|
||||||
|
const { latlng } = e;
|
||||||
|
|
||||||
|
this.stickers.createSticker({ latlng, sticker: this.activeSticker });
|
||||||
|
this.setSticker(null);
|
||||||
|
};
|
||||||
|
|
||||||
changeMode = mode => {
|
changeMode = mode => {
|
||||||
if (this.mode === mode) {
|
if (this.mode === mode) {
|
||||||
this.disableMode(mode);
|
this.disableMode(mode);
|
||||||
|
@ -108,5 +122,10 @@ export class Editor {
|
||||||
|
|
||||||
pushPolyPoints = latlngs => {
|
pushPolyPoints = latlngs => {
|
||||||
this.poly.pushPoints(latlngs);
|
this.poly.pushPoints(latlngs);
|
||||||
}
|
};
|
||||||
|
|
||||||
|
setSticker = sticker => {
|
||||||
|
this.activeSticker = sticker;
|
||||||
|
this.setActiveSticker(sticker);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ import stickers from '$sprites/stickers.svg';
|
||||||
|
|
||||||
export class Sticker {
|
export class Sticker {
|
||||||
constructor({
|
constructor({
|
||||||
latlng, deleteSticker, map, lockMapClicks
|
latlng, deleteSticker, map, lockMapClicks, sticker
|
||||||
}) {
|
}) {
|
||||||
this.angle = 2.2;
|
this.angle = 2.2;
|
||||||
this.isDragging = false;
|
this.isDragging = false;
|
||||||
|
@ -26,7 +26,7 @@ export class Sticker {
|
||||||
this.stickerArrow.className = 'sticker-arrow';
|
this.stickerArrow.className = 'sticker-arrow';
|
||||||
this.stickerDelete.className = 'sticker-delete';
|
this.stickerDelete.className = 'sticker-delete';
|
||||||
|
|
||||||
this.stickerImage.innerHTML = this.generateStickerSVG('green-sm');
|
this.stickerImage.innerHTML = this.generateStickerSVG(sticker);
|
||||||
|
|
||||||
this.element.appendChild(this.stickerArrow);
|
this.element.appendChild(this.stickerArrow);
|
||||||
this.element.appendChild(this.stickerImage);
|
this.element.appendChild(this.stickerImage);
|
||||||
|
|
|
@ -19,17 +19,18 @@ export class Stickers {
|
||||||
this.createSticker({ latlng });
|
this.createSticker({ latlng });
|
||||||
};
|
};
|
||||||
|
|
||||||
createSticker = ({ latlng }) => {
|
createSticker = ({ latlng, sticker }) => {
|
||||||
const sticker = new Sticker({
|
const marker = new Sticker({
|
||||||
latlng,
|
latlng,
|
||||||
deleteSticker: this.deleteStickerByReference,
|
deleteSticker: this.deleteStickerByReference,
|
||||||
map: this.map,
|
map: this.map,
|
||||||
lockMapClicks: this.lockMapClicks,
|
lockMapClicks: this.lockMapClicks,
|
||||||
|
sticker,
|
||||||
});
|
});
|
||||||
this.stickers.push(sticker);
|
this.stickers.push(marker);
|
||||||
|
|
||||||
sticker.sticker.addTo(this.map);
|
marker.sticker.addTo(this.map);
|
||||||
sticker.sticker.enableEdit();
|
marker.sticker.enableEdit();
|
||||||
};
|
};
|
||||||
|
|
||||||
deleteStickerByReference = ref => {
|
deleteStickerByReference = ref => {
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
font-weight: 200;
|
font-weight: 200;
|
||||||
color: #cccccc;
|
color: #cccccc;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
|
box-shadow: rgba(0,0,0,0.3) 0 2px 0, inset rgba(255, 255, 255, 0.05) 1px 1px;
|
||||||
|
|
||||||
svg {
|
svg {
|
||||||
fill: #cccccc;
|
fill: #cccccc;
|
||||||
|
@ -104,11 +105,11 @@
|
||||||
background: #222222;
|
background: #222222;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 10px;
|
right: 10px;
|
||||||
bottom: 10px;
|
bottom: 12px;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
color: white;
|
color: white;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
padding-bottom: 48px;
|
padding-bottom: 48px;
|
||||||
box-shadow: rgba(0,0,0,0.3) 0 2px 0, inset rgba(255, 255, 255, 0.05) 1px 1px;
|
box-shadow: inset rgba(255, 255, 255, 0.05) 1px 1px;
|
||||||
}
|
}
|
||||||
|
|
|
@ -99,3 +99,19 @@
|
||||||
.leaflet-control-container .leaflet-routing-container-hide {
|
.leaflet-control-container .leaflet-routing-container-hide {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.stickers-helper {
|
||||||
|
width: 500px;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sticker-preview {
|
||||||
|
float: left;
|
||||||
|
cursor: pointer;
|
||||||
|
transform: scale(1);
|
||||||
|
transition: transform 250ms;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
transform: scale(1.2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue