diff --git a/package-lock.json b/package-lock.json
index 0d2bfc6..581dc5a 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -11923,6 +11923,11 @@
"integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=",
"dev": true
},
+ "typeface-montserrat": {
+ "version": "0.0.54",
+ "resolved": "https://registry.npmjs.org/typeface-montserrat/-/typeface-montserrat-0.0.54.tgz",
+ "integrity": "sha512-Typhap0PWT299+Va0G/8ZtycHMXrH4gBWKfiW977KEBx5rXUUCa70gvqLx1fdA0WAo6bhSAQmo8uc+QFAmjPww=="
+ },
"ua-parser-js": {
"version": "0.7.18",
"resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.18.tgz",
@@ -12993,6 +12998,11 @@
"integrity": "sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==",
"dev": true
},
+ "wfk-montserrat": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/wfk-montserrat/-/wfk-montserrat-1.0.0.tgz",
+ "integrity": "sha512-XgRPn20Qp20BHs1UXyvMVQgblHSwl3bMhrNeXF921fqxIOT0ZPMynqWa60q5wU5RkRTxQfZsgv0Rt6prMSpvhQ=="
+ },
"whatwg-fetch": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz",
diff --git a/package.json b/package.json
index d39618c..b4ff768 100644
--- a/package.json
+++ b/package.json
@@ -63,7 +63,9 @@
"scrypt": "^6.0.3",
"styled-components": "^3.2.6",
"styled-theming": "^2.2.0",
- "webpack-git-hash": "^1.0.2"
+ "typeface-montserrat": "0.0.54",
+ "webpack-git-hash": "^1.0.2",
+ "wfk-montserrat": "^1.0.0"
},
"flow-coverage-report": {
"includeGlob": [
diff --git a/src/components/Fills.jsx b/src/components/Fills.jsx
index faf3146..084c79b 100644
--- a/src/components/Fills.jsx
+++ b/src/components/Fills.jsx
@@ -11,7 +11,7 @@ export const Fills = () => (
-
+
diff --git a/src/components/panels/EditorDialog.jsx b/src/components/panels/EditorDialog.jsx
new file mode 100644
index 0000000..cd2fc14
--- /dev/null
+++ b/src/components/panels/EditorDialog.jsx
@@ -0,0 +1,14 @@
+import React from 'react';
+import { MODES } from '$constants/modes';
+
+import { RouterHelper } from '$components/router/RouterHelper';
+
+export const EditorDialog = ({ mode, routerPoints }) => {
+ const showDialog = (mode === MODES.ROUTER);
+ return (
+ showDialog &&
+
+ { mode === MODES.ROUTER && }
+
+ );
+};
diff --git a/src/components/panels/EditorPanel.jsx b/src/components/panels/EditorPanel.jsx
index 58e3152..f8def92 100644
--- a/src/components/panels/EditorPanel.jsx
+++ b/src/components/panels/EditorPanel.jsx
@@ -2,7 +2,8 @@ import React from 'react';
import { MODES } from '$constants/modes';
import classnames from 'classnames';
-import { Icon } from '$components/Icon';
+import { Icon } from '$components/panels/Icon';
+import { EditorDialog } from '$components/panels/EditorDialog';
export class EditorPanel extends React.PureComponent {
startPolyMode = () => this.props.editor.changeMode(MODES.POLY);
@@ -14,35 +15,69 @@ export class EditorPanel extends React.PureComponent {
startShotterMode = () => this.props.editor.changeMode(MODES.SHOTTER);
render() {
- const { mode } = this.props;
+ const { mode, routerPoints } = this.props;
return (
-
-
-
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
);
}
diff --git a/src/components/Icon.jsx b/src/components/panels/Icon.jsx
similarity index 66%
rename from src/components/Icon.jsx
rename to src/components/panels/Icon.jsx
index cb59aae..81f731d 100644
--- a/src/components/Icon.jsx
+++ b/src/components/panels/Icon.jsx
@@ -2,7 +2,7 @@ import React from 'react';
import sprite from '$sprites/icon.svg';
export const Icon = ({ icon, size = 32 }) => (
-
diff --git a/src/styles/button.less b/src/styles/button.less
new file mode 100644
index 0000000..eb4153a
--- /dev/null
+++ b/src/styles/button.less
@@ -0,0 +1,35 @@
+.button {
+ background: #444444;
+ padding: 4px 16px;
+ height: 18px;
+ line-height: 1em;
+ border-radius: 2px;
+ font-family: sans-serif;
+ font-size: 14px;
+ display: inline-flex;
+ align-items: center;
+ cursor: pointer;
+ user-select: none;
+
+ &.primary {
+ background: #3c78db;
+ }
+
+ &.danger {
+ background: #ed2f3b;
+ }
+}
+
+.button-group {
+ .button {
+ border-radius: 0;
+
+ &:first-child {
+ border-radius: 4px 0 0 4px;
+ }
+
+ &:last-child {
+ border-radius: 0 4px 4px 0;
+ }
+ }
+}
diff --git a/src/styles/controls.less b/src/styles/controls.less
deleted file mode 100644
index 7038361..0000000
--- a/src/styles/controls.less
+++ /dev/null
@@ -1,35 +0,0 @@
-
-#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;
- }
- }
-}
diff --git a/src/styles/controlsScreen.js b/src/styles/controlsScreen.js
deleted file mode 100644
index 8d07ef4..0000000
--- a/src/styles/controlsScreen.js
+++ /dev/null
@@ -1,13 +0,0 @@
-import styled from 'styled-components';
-
-export const ControlsScreen = styled.div`
- position: fixed;
- right: 10px;
- bottom: 10px;
- height: 48px;
- min-width: 120px;
- background: #333333;
- border-radius: 2px;
- z-index: 2;
- color: white;
-`;
diff --git a/src/styles/main.less b/src/styles/main.less
new file mode 100644
index 0000000..45ada3c
--- /dev/null
+++ b/src/styles/main.less
@@ -0,0 +1,26 @@
+@import 'map.less';
+@import 'panel.less';
+@import 'router.less';
+@import 'stickers.less';
+@import 'button.less';
+
+body {
+ font-family: sans-serif;
+ font-size: 14px;
+}
+
+.gray {
+ opacity: 0.75;
+}
+
+.big {
+ font-size: 14px;
+}
+
+.small {
+ font-size: 12px;
+}
+
+.white {
+ color: white;
+}
diff --git a/src/styles/map.less b/src/styles/map.less
index 1427a16..cc45a2f 100644
--- a/src/styles/map.less
+++ b/src/styles/map.less
@@ -38,139 +38,3 @@
.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;
- }
-}
diff --git a/src/styles/mapScreen.js b/src/styles/mapScreen.js
deleted file mode 100644
index 5f0cfb4..0000000
--- a/src/styles/mapScreen.js
+++ /dev/null
@@ -1,162 +0,0 @@
-import styled, { css } from 'styled-components';
-
-const vertexMixin = css`
- .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;
- }
-`;
-
-const routerMixin = css`
- .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;
- }
- }
-`;
-
-const stickers = css`
- .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;
- }
-
- :hover {
- .sticker-delete {
- transform: scale(1);
- pointer-events: all;
- }
-
- ::before {
- opacity: 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: ${24 - 40}px;
- top: ${24 - 40}px;
- 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;
- }
- }
-`;
-
-export const MapScreen = styled.div.attrs({ id: 'map' })`
- width: 100%;
- height: 100%;
- position: absolute;
- z-index: 1;
- left: 0;
- top: 0;
-
- ${vertexMixin}
- ${stickers}
- ${routerMixin}
-`;
diff --git a/src/styles/panel.less b/src/styles/panel.less
new file mode 100644
index 0000000..ff029de
--- /dev/null
+++ b/src/styles/panel.less
@@ -0,0 +1,92 @@
+.control-bar {
+ background: #333333;
+ border-radius: 3px;
+ display: flex;
+ box-shadow: rgba(0,0,0,0.3) 0 2px 0, inset rgba(255, 255, 255, 0.05) 1px 1px;
+}
+
+.control-sep {
+ height: 44px;
+ background: #222222;
+ width: 3px;
+}
+
+.panel {
+ position: fixed;
+ left: 10px;
+ bottom: 10px;
+ z-index: 3;
+ color: white;
+ display: flex;
+ align-items: center;
+
+ &.right {
+ left: auto;
+ right: 10px;
+ }
+
+ button {
+ border: none;
+ background: transparent;
+ padding: 8px;
+ outline: none;
+ cursor: pointer;
+ display: inline-flex;
+ color: white;
+ align-items: center;
+ transition: background-color 500ms;
+ height: 48px;
+ box-sizing: border-box;
+
+ &:hover {
+ background: rgba(100, 100, 100, 0.2);
+ }
+
+ span {
+ margin-right: 8px;
+ font-size: 14px;
+ font-weight: 200;
+ margin-left: 8px;
+ }
+
+ &:last-child {
+ border-radius: 0 4px 4px 0;
+ }
+
+ &.active {
+ svg {
+ fill: url(#activeButtonGradient);
+ stroke: url(#activeButtonGradient);
+ }
+ }
+
+ &.highlighted {
+ background: linear-gradient(150deg, #05a4ff, #7137c8);
+ }
+
+ svg {
+ fill: white;
+ stroke: white;
+ display: inline;
+ }
+ }
+}
+
+.panel-separator {
+ height: 48px;
+ width: 4px;
+ background: #222222;
+}
+
+#control-dialog {
+ background: #222222;
+ position: absolute;
+ right: 10px;
+ bottom: 10px;
+ 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;
+}
diff --git a/src/styles/router.less b/src/styles/router.less
new file mode 100644
index 0000000..41ff47e
--- /dev/null
+++ b/src/styles/router.less
@@ -0,0 +1,36 @@
+.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;
+ }
+}
+
+.router-helper {
+ width: 500px;
+ padding: 10px;
+ font-weight: 200;
+ font-size: 14px;
+ display: flex;
+}
+
+.router-helper__text {
+ width: 100%;
+}
+
+.router-helper__buttons {
+ display: flex;
+ align-items: center;
+}
diff --git a/src/styles/stickers.less b/src/styles/stickers.less
new file mode 100644
index 0000000..2201b9f
--- /dev/null
+++ b/src/styles/stickers.less
@@ -0,0 +1,95 @@
+.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(1);
+ opacity: 1;
+ pointer-events: none;
+
+ &:hover {
+ transform: scale(1.2) !important;
+ }
+}
+
+.leaflet-control-container .leaflet-routing-container-hide {
+ display: none;
+}