Implement style loading and passing to map component

This commit is contained in:
lukasmartinelli 2016-09-09 00:10:54 +02:00
parent 392a7aa832
commit 7f9fb4579e
13 changed files with 84 additions and 143 deletions

View file

@ -17,12 +17,14 @@
"homepage": "https://github.com/lukasmartinelli/mapolo#readme",
"dependencies": {
"mapbox-gl": "^0.23.0",
"mapbox-gl-style-spec": "^8.8.0",
"node-sass": "^3.9.2",
"react": "15.3.0",
"react-dom": "15.3.0",
"react-file-reader-input": "^1.1.0",
"react-geomicons": "^2.0.5",
"react-icons": "^2.2.1",
"react-mapbox-gl": "^0.11.0",
"react-tap-event-plugin": "^1.0.0",
"rebass": "^0.3.1",
"sass-loader": "^4.0.1"

View file

@ -1,14 +1,21 @@
import {Workspace} from './workspace.jsx';
import {Map} from './map.jsx';
import {Toolbar} from './toolbar.jsx';
import React from 'react';
import styles from './layout.scss';
import React from 'react'
import { Drawer, Container, Block, Fixed } from 'rebass'
import {Map} from './map.jsx'
import {Toolbar} from './toolbar.jsx'
import { LayerEditor } from './layers.jsx'
import theme from './theme.jsx'
import theme from './theme.js'
import layout from './layout.scss'
export class WorkspaceDrawer extends React.Component {
render() {
let editor = null
if(this.props.mapStyle) {
editor = <LayerEditor layers={this.props.mapStyle.layers}/>
}
return <Container style={{
zIndex: 100,
position: "fixed",
@ -19,8 +26,8 @@ export class WorkspaceDrawer extends React.Component {
bottom: "0",
backgroundColor: theme.colors.gray}
} >
<LayerEditor />
</Container>;
{editor}
</Container>
}
}
@ -30,6 +37,18 @@ export default class App extends React.Component {
reactIconBase: React.PropTypes.object
}
constructor(props) {
super(props)
this.updateStyle = this.updateStyle.bind(this);
this.state = {
mapStyle: null
}
}
updateStyle(newStyle) {
this.setState({ mapStyle: newStyle })
}
getChildContext () {
return {
rebass: theme,
@ -40,14 +59,13 @@ export default class App extends React.Component {
}
render() {
return (
<div>
<Toolbar />
<WorkspaceDrawer />
<div className={styles.layoutMap}>
<Map />
console.log(this.state.mapStyle)
return <div>
<Toolbar onStyleUpload={this.updateStyle} />
<WorkspaceDrawer mapStyle={this.state.mapStyle} />
<div className={layout.map}>
<Map mapStyle={this.state.mapStyle} />
</div>
</div>
)
}
}

View file

@ -1,4 +0,0 @@
import React from 'react';
import styles from './button.scss';
import { Button, Text } from 'rebass'

View file

@ -1,18 +0,0 @@
.button {
text-align: center;
display: inline-block;
margin: 0px;
padding: 10px;
position: relative;
border: none;
cursor: pointer;
border-radius: 3px;
white-space: nowrap;
text-overflow: ellipsis;
font-family: 'Open Sans Bold', sans-serif;
line-height: 20px;
font-size: 12px;
color: #fff;
background-color: rgba(255,255,255,0.10);
}

View file

@ -1,8 +0,0 @@
.blueBg {
background-color: blue;
color: white;
}
.app {
padding: 0;
}

View file

@ -1,17 +1,23 @@
import React from 'react';
import React from 'react'
import { Toolbar, NavItem, Tooltip, Container, Space} from 'rebass'
import theme from './theme.jsx';
import { Button, Text } from 'rebass';
import { Button, Text } from 'rebass'
import theme from './theme.js'
export class LayerEditor extends React.Component {
render() {
const layerBlocks = this.props.layers.map(layer => {
console.log(layer)
return <Text>{layer.id}</Text>
});
return <Container>
<Toolbar>
<NavItem is="a">
Toolbar
</NavItem>
</Toolbar>
</Container>;
{layerBlocks}
</Container>
}
}

View file

@ -5,7 +5,7 @@
height: 100%;
}
.layoutMap {
.map {
@include full-height;
width: 100%;

View file

@ -1,21 +1,18 @@
import React from 'react';
import MapboxGl from 'mapbox-gl';
import React from 'react'
import ReactMapboxGl from "react-mapbox-gl"
export class Map extends React.Component {
constructor(props) {
super(props);
}
componentDidMount() {
MapboxGl.accessToken = "pk.eyJ1IjoibW9yZ2Vua2FmZmVlIiwiYSI6IjIzcmN0NlkifQ.0LRTNgCc-envt9d5MzR75w";
const map = new MapboxGl.Map({
container: this.container,
style: "mapbox://styles/morgenkaffee/cirqasdb8003dh1ntbo6dkvs6"
});
super(props)
}
render() {
return <div ref={x => this.container = x} style={{zIndex: 15}}></div>
if (this.props.mapStyle) {
return <ReactMapboxGl
style={this.props.mapStyle}
accessToken="pk.eyJ1IjoibW9yZ2Vua2FmZmVlIiwiYSI6IjIzcmN0NlkifQ.0LRTNgCc-envt9d5MzR75w"/>
}
return <div />
}
}

View file

@ -1,27 +1,27 @@
import React from 'react';
export class StyleCommand {
do(map) {
throw new TypeError("Do not implemented");
}
undo(map) {
throw new TypeError("Undo not implemented");
}
// A wrapper around Mapbox GL style
export class Style {
constructor() {
this.styleHistory = [];
this.renderers = [];
}
export class StyleEditor {
constructor(map, style) {
this.map = map;
this.style = style;
this.history = [];
load(style) {
this.currentStyle = style;
}
onRender(cb) {
this.renderers.push(cb);
}
update(style) {
this.styleHistory.push(this.currentStyle);
this.currentStyle = style;
this.renderers.forEach(r => r(this.currentStyle))
}
layers() {
return this.style.layers;
}
execute(command) {
this.history.push(command);
command.do(this.map);
return this.currentStyle.layers;
}
}

View file

@ -1,17 +1,16 @@
import React from 'react';
import { Menu, NavItem, Tooltip, Container, Block, Fixed } from 'rebass'
import theme from './theme.jsx';
import {MdSettings, MdPalette, MdLayers, MdSave, MdFolderOpen} from 'react-icons/lib/md';
import { Button, Text } from 'rebass';
import FileReaderInput from 'react-file-reader-input';
import { Button, Text } from 'rebass';
import { Menu, NavItem, Tooltip, Container, Block, Fixed } from 'rebass'
import {MdSettings, MdPalette, MdLayers, MdSave, MdFolderOpen} from 'react-icons/lib/md';
import theme from './theme.js';
export class Toolbar extends React.Component {
constructor(props) {
super(props);
this.state = {
styleFile: null
};
this.onUpload = this.onUpload.bind(this);
}
onUpload(_, files) {
@ -20,10 +19,11 @@ export class Toolbar extends React.Component {
reader.readAsText(file, "UTF-8");
reader.onload = e => {
const style = JSON.parse(e.target.result);
console.log(style);
this.props.onStyleUpload(style);
}
reader.onerror = e => console.log(e.target);
}
render() {
return <Container style={{
zIndex: 100,

View file

@ -1,50 +0,0 @@
import React from 'react';
import { Space, Toolbar, ButtonCircle, Text, Panel, PanelHeader, PanelFooter } from 'rebass'
import Icon from 'react-geomicons';
export class Workspace extends React.Component {
render() {
return <div className="workspace">
<Toolbar>
<Text>Hey layer</Text>
<Space
auto
x={1}
/>
<ButtonCircle title="Like">
<Icon
fill="currentColor"
height="1em"
name="no"
width="1em"
/>
</ButtonCircle>
<ButtonCircle title="Like">
<Icon
fill="currentColor"
height="1em"
name="trash"
width="1em"
/>
</ButtonCircle>
<ButtonCircle title="Like">
<Icon
fill="currentColor"
height="1em"
name="triangleUp"
width="1em"
/>
</ButtonCircle>
<ButtonCircle title="Like">
<Icon
fill="currentColor"
height="1em"
name="heart"
width="1em"
/>
</ButtonCircle>
</Toolbar>
</div>
}
}

View file

@ -60,8 +60,6 @@ module.exports = {
resolve: {
alias: {
'webworkify': 'webworkify-webpack',
// TODO: otherwise I get a max call stack error in browser?
'mapbox-gl': path.resolve('./node_modules/mapbox-gl/dist/mapbox-gl.js')
},
extensions: ['', '.js', '.jsx']
},