sticker panel with ability to choose

This commit is contained in:
muerwre 2018-08-24 17:04:48 +07:00
parent 40a11297c0
commit f2c9cc4abc
10 changed files with 140 additions and 64 deletions

View file

@ -2,14 +2,19 @@ import React from 'react';
import { MODES } from '$constants/modes';
import { RouterHelper } from '$components/router/RouterHelper';
import { StickersHelper } from '$components/stickers/StickersHelper';
export const EditorDialog = ({ mode, routerPoints, editor }) => {
const showDialog = (mode === MODES.ROUTER);
export const EditorDialog = ({ mode, routerPoints, editor, activeSticker }) => {
const showDialog = (
mode === MODES.ROUTER
|| (mode === MODES.STICKERS && !activeSticker)
);
return (
showDialog &&
<div id="control-dialog">
{ mode === MODES.ROUTER && <RouterHelper routerPoints={routerPoints} editor={editor} /> }
{ mode === MODES.STICKERS && <StickersHelper editor={editor} /> }
</div>
);
};

View file

@ -18,7 +18,7 @@ export class EditorPanel extends React.PureComponent {
render() {
const {
mode, routerPoints, editor, totalDistance, estimateTime
mode, routerPoints, editor, totalDistance, estimateTime, activeSticker
} = this.props;
return (
@ -27,6 +27,7 @@ export class EditorPanel extends React.PureComponent {
<EditorDialog
mode={mode}
routerPoints={routerPoints}
activeSticker={activeSticker}
editor={editor}
/>
@ -51,7 +52,7 @@ export class EditorPanel extends React.PureComponent {
(estimateTime > 0) && (estimateTime > 0) && <span>{toHours(estimateTime)}</span>
}
</React.Fragment>
: <div onClick={() => editor.changeMode(MODES.ROUTER)}>Начнать рисовать</div>
: <div onClick={() => editor.changeMode(MODES.ROUTER)}>Начать рисовать</div>
}
</div>

View 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>
);
}
}

View file

@ -1,43 +1,45 @@
// Стикеры
import L from "leaflet";
// import L from "leaflet";
export const stickers = {
'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"}, // третий ряд
export const stickers = ['green', 'basic', 'green-small'];
{off: 2, title: 'Трасса', title_long: 'Дорога'},
{off: 3, title: 'Курочка', title_long: 'Курочка'},
{off: 6, 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: "Что тут?"}
]
};
// export const _stickers = {
// '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: 'Дорога'},
// {off: 3, title: 'Курочка', title_long: 'Курочка'},
// {off: 6, 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: "Что тут?"}
// ]
// };

View file

@ -10,6 +10,7 @@ export class App extends React.Component {
routerPoints: 0,
totalDistance: 0,
estimateTime: 0,
activeSticker: null,
};
setMode = mode => {
@ -26,18 +27,25 @@ export class App extends React.Component {
this.setState({ totalDistance, estimateTime });
};
setActiveSticker = activeSticker => {
this.setState({ activeSticker });
};
editor = new Editor({
container: 'map',
mode: this.state.mode,
setMode: this.setMode,
setRouterPoints: this.setRouterPoints,
setTotalDist: this.setTotalDist,
setActiveSticker: this.setActiveSticker,
});
render() {
const {
editor,
state: { mode, routerPoints, totalDistance, estimateTime },
state: {
mode, routerPoints, totalDistance, estimateTime, activeSticker
},
} = this;
@ -50,6 +58,7 @@ export class App extends React.Component {
routerPoints={routerPoints}
totalDistance={totalDistance}
estimateTime={estimateTime}
activeSticker={activeSticker}
/>
</div>
);

View file

@ -12,6 +12,7 @@ export class Editor {
setMode,
setRouterPoints,
setTotalDist,
setActiveSticker,
}) {
this.map = new Map({ container });
@ -19,7 +20,9 @@ export class Editor {
lockMapClicks, routerMoveStart, changeMode, pushPolyPoints, map: { map }
} = this;
this.poly = new Poly({ map, routerMoveStart, lockMapClicks, setTotalDist });
this.poly = new Poly({
map, routerMoveStart, lockMapClicks, setTotalDist
});
this.stickers = new Stickers({ map, lockMapClicks });
this.router = new Router({
map, lockMapClicks, setRouterPoints, changeMode, pushPolyPoints
@ -43,15 +46,26 @@ export class Editor {
};
this.clickHandlers = {
[MODES.STICKERS]: this.stickers.createOnClick,
[MODES.STICKERS]: this.createStickerOnClick,
[MODES.ROUTER]: this.router.pushWaypointOnClick,
};
this.activeSticker = null;
this.setActiveSticker = setActiveSticker;
map.addEventListener('mouseup', this.onClick);
map.addEventListener('dragstart', () => lockMapClicks(true));
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 => {
if (this.mode === mode) {
this.disableMode(mode);
@ -108,5 +122,10 @@ export class Editor {
pushPolyPoints = latlngs => {
this.poly.pushPoints(latlngs);
}
};
setSticker = sticker => {
this.activeSticker = sticker;
this.setActiveSticker(sticker);
};
}

View file

@ -7,7 +7,7 @@ import stickers from '$sprites/stickers.svg';
export class Sticker {
constructor({
latlng, deleteSticker, map, lockMapClicks
latlng, deleteSticker, map, lockMapClicks, sticker
}) {
this.angle = 2.2;
this.isDragging = false;
@ -26,7 +26,7 @@ export class Sticker {
this.stickerArrow.className = 'sticker-arrow';
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.stickerImage);

View file

@ -19,17 +19,18 @@ export class Stickers {
this.createSticker({ latlng });
};
createSticker = ({ latlng }) => {
const sticker = new Sticker({
createSticker = ({ latlng, sticker }) => {
const marker = new Sticker({
latlng,
deleteSticker: this.deleteStickerByReference,
map: this.map,
lockMapClicks: this.lockMapClicks,
sticker,
});
this.stickers.push(sticker);
this.stickers.push(marker);
sticker.sticker.addTo(this.map);
sticker.sticker.enableEdit();
marker.sticker.addTo(this.map);
marker.sticker.enableEdit();
};
deleteStickerByReference = ref => {

View file

@ -15,6 +15,7 @@
font-weight: 200;
color: #cccccc;
user-select: none;
box-shadow: rgba(0,0,0,0.3) 0 2px 0, inset rgba(255, 255, 255, 0.05) 1px 1px;
svg {
fill: #cccccc;
@ -104,11 +105,11 @@
background: #222222;
position: absolute;
right: 10px;
bottom: 10px;
bottom: 12px;
border-radius: 3px;
z-index: 2;
color: white;
box-sizing: border-box;
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;
}

View file

@ -99,3 +99,19 @@
.leaflet-control-container .leaflet-routing-container-hide {
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);
}
}