mirror of
https://github.com/google-map-react/google-map-react.git
synced 2025-12-08 18:26:32 +00:00
Move 2 yarn, add prettier, update linters (#360)
* Move 2 yarn, add prettier, update linters * Fix linting error
This commit is contained in:
parent
1b088ceef5
commit
07368e23ad
72
.eslintrc
72
.eslintrc
@ -1,29 +1,65 @@
|
||||
{
|
||||
"extends": "airbnb",
|
||||
"extends": [
|
||||
"airbnb",
|
||||
"prettier",
|
||||
"prettier/flowtype",
|
||||
"prettier/react"
|
||||
],
|
||||
"plugins": [
|
||||
"babel",
|
||||
"prettier"
|
||||
],
|
||||
"parser": "babel-eslint",
|
||||
"env": {
|
||||
"es6": true,
|
||||
"browser": true,
|
||||
"mocha": true,
|
||||
"jest": true,
|
||||
"node": true
|
||||
},
|
||||
"globals": {
|
||||
"__DEV__": false,
|
||||
"__DEV_TOOLS__": false
|
||||
},
|
||||
"rules": {
|
||||
"no-confusing-arrow": 0,
|
||||
"no-nested-ternary": 0,
|
||||
"yoda": 0,
|
||||
"no-underscore-dangle": 0,
|
||||
"react/prop-types": 0
|
||||
},
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 6,
|
||||
"ecmaVersion": 2017,
|
||||
"sourceType": "module",
|
||||
"ecmaFeatures": {
|
||||
"jsx": true,
|
||||
"generators": true,
|
||||
"experimentalObjectRestSpread": true
|
||||
}
|
||||
},
|
||||
"plugins": [
|
||||
"react"
|
||||
],
|
||||
"parser": "babel-eslint"
|
||||
}
|
||||
"rules": {
|
||||
"no-bitwise": 0,
|
||||
"no-nested-ternary": 0,
|
||||
"react/prop-types": 0,
|
||||
"react/jsx-filename-extension": 0,
|
||||
"react/require-default-props": 0,
|
||||
"react/no-unused-prop-types": 0,
|
||||
"no-sequences": 1,
|
||||
"comma-dangle": 0,
|
||||
"no-mixed-operators": 0,
|
||||
"no-underscore-dangle": 0,
|
||||
"no-restricted-properties": 0,
|
||||
"jsx-a11y/no-static-element-interactions": 0,
|
||||
"import/no-extraneous-dependencies": 0,
|
||||
"no-plusplus": 0,
|
||||
"no-unused-vars": [
|
||||
"error",
|
||||
{
|
||||
"ignoreRestSiblings": true
|
||||
}
|
||||
],
|
||||
"react/sort-comp": 0,
|
||||
"prettier/prettier": [
|
||||
"error",
|
||||
{
|
||||
"trailingComma": "es5",
|
||||
"singleQuote": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"settings": {
|
||||
"polyfills": [
|
||||
"fetch__"
|
||||
]
|
||||
},
|
||||
"globals": {}
|
||||
}
|
||||
@ -5,5 +5,5 @@ cache:
|
||||
directories:
|
||||
- node_modules
|
||||
script:
|
||||
- npm run lint
|
||||
- npm test
|
||||
- yarn run lint
|
||||
- yarn test
|
||||
|
||||
4
.vscode/settings.json
vendored
Normal file
4
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
// Place your settings in this file to overwrite default and user settings.
|
||||
{
|
||||
"editor.formatOnSave": true
|
||||
}
|
||||
100
develop/GMap.js
100
develop/GMap.js
@ -1,24 +1,31 @@
|
||||
import React, { PropTypes } from 'react';
|
||||
import compose from 'recompose/compose';
|
||||
import defaultProps from 'recompose/defaultProps';
|
||||
import withStateSelector from './utils/withStateSelector';
|
||||
import withHandlers from 'recompose/withHandlers';
|
||||
import withState from 'recompose/withState';
|
||||
import withContext from 'recompose/withContext';
|
||||
import withProps from 'recompose/withProps';
|
||||
import withPropsOnChange from 'recompose/withPropsOnChange';
|
||||
import ptInBounds from './utils/ptInBounds';
|
||||
import GoogleMapReact from '../src';
|
||||
import SimpleMarker from './markers/SimpleMarker';
|
||||
import { createSelector } from 'reselect';
|
||||
import ptInBounds from './utils/ptInBounds';
|
||||
import SimpleMarker from './markers/SimpleMarker';
|
||||
import withStateSelector from './utils/withStateSelector';
|
||||
import GoogleMapReact from '../src';
|
||||
import { susolvkaCoords, generateMarkers } from './data/fakeData';
|
||||
|
||||
export const gMap = ({
|
||||
style, hoverDistance, options,
|
||||
mapParams: { center, zoom },
|
||||
onChange, onChildMouseEnter, onChildMouseLeave,
|
||||
markers, draggable, // hoveredMarkerId,
|
||||
}) => (
|
||||
export const gMap = (
|
||||
{
|
||||
style,
|
||||
hoverDistance,
|
||||
options,
|
||||
mapParams: { center, zoom },
|
||||
onChange,
|
||||
onChildMouseEnter,
|
||||
onChildMouseLeave,
|
||||
markers,
|
||||
draggable, // hoveredMarkerId,
|
||||
}
|
||||
) => (
|
||||
<GoogleMapReact
|
||||
draggable={draggable}
|
||||
style={style}
|
||||
@ -30,9 +37,7 @@ export const gMap = ({
|
||||
onChildMouseEnter={onChildMouseEnter}
|
||||
onChildMouseLeave={onChildMouseLeave}
|
||||
>
|
||||
{
|
||||
markers
|
||||
}
|
||||
{markers}
|
||||
</GoogleMapReact>
|
||||
);
|
||||
|
||||
@ -51,57 +56,44 @@ export const gMapHOC = compose(
|
||||
flex: 1,
|
||||
},
|
||||
}),
|
||||
withContext(
|
||||
{ hello: PropTypes.string },
|
||||
() => ({ hello: 'world' })
|
||||
),
|
||||
withContext({ hello: PropTypes.string }, () => ({ hello: 'world' })),
|
||||
// withState so you could change markers if you want
|
||||
withStateSelector(
|
||||
'markers',
|
||||
'setMarkers',
|
||||
() => createSelector(
|
||||
withStateSelector('markers', 'setMarkers', () =>
|
||||
createSelector(
|
||||
({ route: { markersCount = 20 } }) => markersCount,
|
||||
(markersCount) => generateMarkers(markersCount)
|
||||
)
|
||||
),
|
||||
markersCount => generateMarkers(markersCount)
|
||||
)),
|
||||
withState('hoveredMarkerId', 'setHoveredMarkerId', -1),
|
||||
withState('mapParams', 'setMapParams', { center: susolvkaCoords, zoom: 6 }),
|
||||
// describe events
|
||||
withHandlers({
|
||||
onChange: ({ setMapParams }) => ({ center, zoom, bounds }) => {
|
||||
setMapParams({ center, zoom, bounds });
|
||||
},
|
||||
onChildMouseEnter: ({ setHoveredMarkerId }) => (hoverKey, { id }) => {
|
||||
setHoveredMarkerId(id);
|
||||
},
|
||||
onChildMouseLeave: ({ setHoveredMarkerId }) => () => {
|
||||
setHoveredMarkerId(-1);
|
||||
},
|
||||
onChange: ({ setMapParams }) =>
|
||||
({ center, zoom, bounds }) => {
|
||||
setMapParams({ center, zoom, bounds });
|
||||
},
|
||||
onChildMouseEnter: ({ setHoveredMarkerId }) =>
|
||||
(hoverKey, { id }) => {
|
||||
setHoveredMarkerId(id);
|
||||
},
|
||||
onChildMouseLeave: ({ setHoveredMarkerId }) =>
|
||||
() => {
|
||||
setHoveredMarkerId(-1);
|
||||
},
|
||||
}),
|
||||
withPropsOnChange(
|
||||
['markers', 'mapParams'],
|
||||
({ markers, mapParams: { bounds } }) => ({
|
||||
markers: bounds
|
||||
? markers.filter(m => ptInBounds(bounds, m))
|
||||
: [],
|
||||
})
|
||||
),
|
||||
withPropsOnChange(['markers', 'mapParams'], ({
|
||||
markers,
|
||||
mapParams: { bounds },
|
||||
}) => ({
|
||||
markers: bounds ? markers.filter(m => ptInBounds(bounds, m)) : [],
|
||||
})),
|
||||
withProps(({ hoveredMarkerId }) => ({
|
||||
draggable: hoveredMarkerId === -1,
|
||||
})),
|
||||
withPropsOnChange(
|
||||
['markers'],
|
||||
({ markers }) => ({
|
||||
markers: markers
|
||||
.map(({ ...markerProps, id }) => (
|
||||
<SimpleMarker
|
||||
key={id}
|
||||
id={id}
|
||||
{...markerProps}
|
||||
/>
|
||||
)),
|
||||
})
|
||||
)
|
||||
withPropsOnChange(['markers'], ({ markers }) => ({
|
||||
markers: markers.map(({ ...markerProps, id }) => (
|
||||
<SimpleMarker key={id} id={id} {...markerProps} />
|
||||
)),
|
||||
}))
|
||||
);
|
||||
|
||||
export default gMapHOC(gMap);
|
||||
|
||||
@ -1,24 +1,31 @@
|
||||
import React, { PropTypes } from 'react';
|
||||
import compose from 'recompose/compose';
|
||||
import defaultProps from 'recompose/defaultProps';
|
||||
import withStateSelector from './utils/withStateSelector';
|
||||
import withHandlers from 'recompose/withHandlers';
|
||||
import withState from 'recompose/withState';
|
||||
import withContext from 'recompose/withContext';
|
||||
import withProps from 'recompose/withProps';
|
||||
import withPropsOnChange from 'recompose/withPropsOnChange';
|
||||
import { createSelector } from 'reselect';
|
||||
import ptInBounds from './utils/ptInBounds';
|
||||
import GoogleMapReact from '../src';
|
||||
import withStateSelector from './utils/withStateSelector';
|
||||
import SimpleMarker from './markers/SimpleMarker';
|
||||
import { createSelector } from 'reselect';
|
||||
import { londonCoords, generateMarkers } from './data/fakeData';
|
||||
|
||||
export const gMap = ({
|
||||
style, hoverDistance, options,
|
||||
mapParams: { center, zoom },
|
||||
onChange, onChildMouseEnter, onChildMouseLeave,
|
||||
markers, draggable, // hoveredMarkerId,
|
||||
}) => (
|
||||
export const gMap = (
|
||||
{
|
||||
style,
|
||||
hoverDistance,
|
||||
options,
|
||||
mapParams: { center, zoom },
|
||||
onChange,
|
||||
onChildMouseEnter,
|
||||
onChildMouseLeave,
|
||||
markers,
|
||||
draggable, // hoveredMarkerId,
|
||||
}
|
||||
) => (
|
||||
<GoogleMapReact
|
||||
draggable={draggable}
|
||||
style={style}
|
||||
@ -26,14 +33,16 @@ export const gMap = ({
|
||||
hoverDistance={hoverDistance}
|
||||
center={center}
|
||||
zoom={zoom}
|
||||
layerTypes={zoom > 12 ? [] : zoom > 10 ? ['TrafficLayer'] : ['TrafficLayer', 'TransitLayer']}
|
||||
layerTypes={
|
||||
zoom > 12
|
||||
? []
|
||||
: zoom > 10 ? ['TrafficLayer'] : ['TrafficLayer', 'TransitLayer']
|
||||
}
|
||||
onChange={onChange}
|
||||
onChildMouseEnter={onChildMouseEnter}
|
||||
onChildMouseLeave={onChildMouseLeave}
|
||||
>
|
||||
{
|
||||
markers
|
||||
}
|
||||
{markers}
|
||||
</GoogleMapReact>
|
||||
);
|
||||
|
||||
@ -52,57 +61,44 @@ export const gMapHOC = compose(
|
||||
flex: 1,
|
||||
},
|
||||
}),
|
||||
withContext(
|
||||
{ hello: PropTypes.string },
|
||||
() => ({ hello: 'world' })
|
||||
),
|
||||
withContext({ hello: PropTypes.string }, () => ({ hello: 'world' })),
|
||||
// withState so you could change markers if you want
|
||||
withStateSelector(
|
||||
'markers',
|
||||
'setMarkers',
|
||||
() => createSelector(
|
||||
withStateSelector('markers', 'setMarkers', () =>
|
||||
createSelector(
|
||||
({ route: { markersCount = 20 } }) => markersCount,
|
||||
(markersCount) => generateMarkers(markersCount)
|
||||
)
|
||||
),
|
||||
markersCount => generateMarkers(markersCount)
|
||||
)),
|
||||
withState('hoveredMarkerId', 'setHoveredMarkerId', -1),
|
||||
withState('mapParams', 'setMapParams', { center: londonCoords, zoom: 9 }),
|
||||
// describe events
|
||||
withHandlers({
|
||||
onChange: ({ setMapParams }) => ({ center, zoom, bounds }) => {
|
||||
setMapParams({ center, zoom, bounds });
|
||||
},
|
||||
onChildMouseEnter: ({ setHoveredMarkerId }) => (hoverKey, { id }) => {
|
||||
setHoveredMarkerId(id);
|
||||
},
|
||||
onChildMouseLeave: ({ setHoveredMarkerId }) => () => {
|
||||
setHoveredMarkerId(-1);
|
||||
},
|
||||
onChange: ({ setMapParams }) =>
|
||||
({ center, zoom, bounds }) => {
|
||||
setMapParams({ center, zoom, bounds });
|
||||
},
|
||||
onChildMouseEnter: ({ setHoveredMarkerId }) =>
|
||||
(hoverKey, { id }) => {
|
||||
setHoveredMarkerId(id);
|
||||
},
|
||||
onChildMouseLeave: ({ setHoveredMarkerId }) =>
|
||||
() => {
|
||||
setHoveredMarkerId(-1);
|
||||
},
|
||||
}),
|
||||
withPropsOnChange(
|
||||
['markers', 'mapParams'],
|
||||
({ markers, mapParams: { bounds } }) => ({
|
||||
markers: bounds
|
||||
? markers.filter(m => ptInBounds(bounds, m))
|
||||
: [],
|
||||
})
|
||||
),
|
||||
withPropsOnChange(['markers', 'mapParams'], ({
|
||||
markers,
|
||||
mapParams: { bounds },
|
||||
}) => ({
|
||||
markers: bounds ? markers.filter(m => ptInBounds(bounds, m)) : [],
|
||||
})),
|
||||
withProps(({ hoveredMarkerId }) => ({
|
||||
draggable: hoveredMarkerId === -1,
|
||||
})),
|
||||
withPropsOnChange(
|
||||
['markers'],
|
||||
({ markers }) => ({
|
||||
markers: markers
|
||||
.map(({ ...markerProps, id }) => (
|
||||
<SimpleMarker
|
||||
key={id}
|
||||
id={id}
|
||||
{...markerProps}
|
||||
/>
|
||||
)),
|
||||
})
|
||||
)
|
||||
withPropsOnChange(['markers'], ({ markers }) => ({
|
||||
markers: markers.map(({ ...markerProps, id }) => (
|
||||
<SimpleMarker key={id} id={id} {...markerProps} />
|
||||
)),
|
||||
}))
|
||||
);
|
||||
|
||||
export default gMapHOC(gMap);
|
||||
|
||||
@ -8,25 +8,32 @@
|
||||
import React from 'react';
|
||||
import compose from 'recompose/compose';
|
||||
import defaultProps from 'recompose/defaultProps';
|
||||
import withStateSelector from './utils/withStateSelector';
|
||||
import withHandlers from 'recompose/withHandlers';
|
||||
import withState from 'recompose/withState';
|
||||
import withPropsOnChange from 'recompose/withPropsOnChange';
|
||||
import withProps from 'recompose/withProps';
|
||||
import { createSelector } from 'reselect';
|
||||
import withStateSelector from './utils/withStateSelector';
|
||||
import ptInBounds from './utils/ptInBounds';
|
||||
import GoogleMapReact from '../src';
|
||||
// import SimpleMarker from './markers/SimpleMarker';
|
||||
import ReactiveMarker from './markers/ReactiveMarker';
|
||||
import { createSelector } from 'reselect';
|
||||
import { susolvkaCoords, generateMarkers } from './data/fakeData';
|
||||
import props2Stream from './utils/props2Stream';
|
||||
|
||||
export const gMap = ({
|
||||
style, hoverDistance, options,
|
||||
mapParams: { center, zoom },
|
||||
onChange, onChildMouseEnter, onChildMouseLeave,
|
||||
markers, draggable,
|
||||
}) => (
|
||||
export const gMap = (
|
||||
{
|
||||
style,
|
||||
hoverDistance,
|
||||
options,
|
||||
mapParams: { center, zoom },
|
||||
onChange,
|
||||
onChildMouseEnter,
|
||||
onChildMouseLeave,
|
||||
markers,
|
||||
draggable,
|
||||
}
|
||||
) => (
|
||||
<GoogleMapReact
|
||||
style={style}
|
||||
options={options}
|
||||
@ -58,56 +65,52 @@ export const gMapHOC = compose(
|
||||
flex: 1,
|
||||
},
|
||||
}),
|
||||
|
||||
// withState so you could change markers if you want
|
||||
withStateSelector(
|
||||
'markers',
|
||||
'setMarkers',
|
||||
() => createSelector(
|
||||
withStateSelector('markers', 'setMarkers', () =>
|
||||
createSelector(
|
||||
({ route: { markersCount = 20 } }) => markersCount,
|
||||
(markersCount) => generateMarkers(markersCount)
|
||||
)
|
||||
),
|
||||
markersCount => generateMarkers(markersCount)
|
||||
)),
|
||||
withState('hoveredMarkerId', 'setHoveredMarkerId', -1),
|
||||
withState('mapParams', 'setMapParams', { center: susolvkaCoords, zoom: 6 }),
|
||||
// describe events
|
||||
withHandlers({
|
||||
onChange: ({ setMapParams }) => ({ center, zoom, bounds }) => {
|
||||
setMapParams({ center, zoom, bounds });
|
||||
},
|
||||
onChildMouseEnter: ({ setHoveredMarkerId }) => (hoverKey, { id }) => {
|
||||
setHoveredMarkerId(id);
|
||||
},
|
||||
onChildMouseLeave: ({ setHoveredMarkerId }) => () => {
|
||||
setHoveredMarkerId(-1);
|
||||
},
|
||||
onChange: ({ setMapParams }) =>
|
||||
({ center, zoom, bounds }) => {
|
||||
setMapParams({ center, zoom, bounds });
|
||||
},
|
||||
onChildMouseEnter: ({ setHoveredMarkerId }) =>
|
||||
(hoverKey, { id }) => {
|
||||
setHoveredMarkerId(id);
|
||||
},
|
||||
onChildMouseLeave: ({ setHoveredMarkerId }) =>
|
||||
() => {
|
||||
setHoveredMarkerId(-1);
|
||||
},
|
||||
}),
|
||||
withPropsOnChange(
|
||||
['markers', 'mapParams'],
|
||||
({ markers, mapParams: { bounds } }) => ({
|
||||
markers: bounds
|
||||
? markers.filter(m => ptInBounds(bounds, m))
|
||||
: [],
|
||||
})
|
||||
),
|
||||
withPropsOnChange(['markers', 'mapParams'], ({
|
||||
markers,
|
||||
mapParams: { bounds },
|
||||
}) => ({
|
||||
markers: bounds ? markers.filter(m => ptInBounds(bounds, m)) : [],
|
||||
})),
|
||||
withProps(({ hoveredMarkerId }) => ({
|
||||
draggable: hoveredMarkerId === -1,
|
||||
})),
|
||||
props2Stream('hoveredMarkerId'),
|
||||
withPropsOnChange(
|
||||
['markers', 'hoveredMarkerId$'],
|
||||
({ markers, hoveredMarkerId$ }) => ({
|
||||
markers: markers
|
||||
.map(({ ...markerProps, id }) => (
|
||||
<ReactiveMarker
|
||||
key={id}
|
||||
id={id}
|
||||
hoveredMarkerId$={hoveredMarkerId$}
|
||||
{...markerProps}
|
||||
/>
|
||||
)),
|
||||
})
|
||||
)
|
||||
withPropsOnChange(['markers', 'hoveredMarkerId$'], ({
|
||||
markers,
|
||||
hoveredMarkerId$,
|
||||
}) => ({
|
||||
markers: markers.map(({ ...markerProps, id }) => (
|
||||
<ReactiveMarker
|
||||
key={id}
|
||||
id={id}
|
||||
hoveredMarkerId$={hoveredMarkerId$}
|
||||
{...markerProps}
|
||||
/>
|
||||
)),
|
||||
}))
|
||||
);
|
||||
|
||||
export default gMapHOC(gMap);
|
||||
|
||||
@ -14,12 +14,19 @@ import SimpleMarker from './markers/SimpleMarker';
|
||||
import { createSelector } from 'reselect';
|
||||
import { susolvkaCoords, generateMarkers } from './data/fakeData';
|
||||
|
||||
export const gMapResizable = ({
|
||||
style, hoverDistance, options,
|
||||
mapParams: { center, zoom },
|
||||
onChange, onChildMouseEnter, onChildMouseLeave,
|
||||
markers, draggable, // hoveredMarkerId,
|
||||
}) => (
|
||||
export const gMapResizable = (
|
||||
{
|
||||
style,
|
||||
hoverDistance,
|
||||
options,
|
||||
mapParams: { center, zoom },
|
||||
onChange,
|
||||
onChildMouseEnter,
|
||||
onChildMouseLeave,
|
||||
markers,
|
||||
draggable, // hoveredMarkerId,
|
||||
}
|
||||
) => (
|
||||
<GoogleMapReact
|
||||
draggable={draggable}
|
||||
style={style}
|
||||
@ -31,11 +38,9 @@ export const gMapResizable = ({
|
||||
onChildMouseEnter={onChildMouseEnter}
|
||||
onChildMouseLeave={onChildMouseLeave}
|
||||
resetBoundsOnResize={true}
|
||||
apiKey={"AIzaSyC-BebC7ChnHPzxQm7DAHYFMCqR5H3Jlps"}
|
||||
apiKey={'AIzaSyC-BebC7ChnHPzxQm7DAHYFMCqR5H3Jlps'}
|
||||
>
|
||||
{
|
||||
markers
|
||||
}
|
||||
{markers}
|
||||
</GoogleMapReact>
|
||||
);
|
||||
|
||||
@ -54,57 +59,44 @@ export const gMapHOC = compose(
|
||||
flex: 1,
|
||||
},
|
||||
}),
|
||||
withContext(
|
||||
{ hello: PropTypes.string },
|
||||
() => ({ hello: 'world' })
|
||||
),
|
||||
withContext({ hello: PropTypes.string }, () => ({ hello: 'world' })),
|
||||
// withState so you could change markers if you want
|
||||
withStateSelector(
|
||||
'markers',
|
||||
'setMarkers',
|
||||
() => createSelector(
|
||||
withStateSelector('markers', 'setMarkers', () =>
|
||||
createSelector(
|
||||
({ route: { markersCount = 20 } }) => markersCount,
|
||||
(markersCount) => generateMarkers(markersCount)
|
||||
)
|
||||
),
|
||||
markersCount => generateMarkers(markersCount)
|
||||
)),
|
||||
withState('hoveredMarkerId', 'setHoveredMarkerId', -1),
|
||||
withState('mapParams', 'setMapParams', { center: susolvkaCoords, zoom: 6 }),
|
||||
// describe events
|
||||
withHandlers({
|
||||
onChange: ({ setMapParams }) => ({ center, zoom, bounds }) => {
|
||||
setMapParams({ center, zoom, bounds });
|
||||
},
|
||||
onChildMouseEnter: ({ setHoveredMarkerId }) => (hoverKey, { id }) => {
|
||||
setHoveredMarkerId(id);
|
||||
},
|
||||
onChildMouseLeave: ({ setHoveredMarkerId }) => () => {
|
||||
setHoveredMarkerId(-1);
|
||||
},
|
||||
onChange: ({ setMapParams }) =>
|
||||
({ center, zoom, bounds }) => {
|
||||
setMapParams({ center, zoom, bounds });
|
||||
},
|
||||
onChildMouseEnter: ({ setHoveredMarkerId }) =>
|
||||
(hoverKey, { id }) => {
|
||||
setHoveredMarkerId(id);
|
||||
},
|
||||
onChildMouseLeave: ({ setHoveredMarkerId }) =>
|
||||
() => {
|
||||
setHoveredMarkerId(-1);
|
||||
},
|
||||
}),
|
||||
withPropsOnChange(
|
||||
['markers', 'mapParams'],
|
||||
({ markers, mapParams: { bounds } }) => ({
|
||||
markers: bounds
|
||||
? markers.filter(m => ptInBounds(bounds, m))
|
||||
: [],
|
||||
})
|
||||
),
|
||||
withPropsOnChange(['markers', 'mapParams'], ({
|
||||
markers,
|
||||
mapParams: { bounds },
|
||||
}) => ({
|
||||
markers: bounds ? markers.filter(m => ptInBounds(bounds, m)) : [],
|
||||
})),
|
||||
withProps(({ hoveredMarkerId }) => ({
|
||||
draggable: hoveredMarkerId === -1,
|
||||
})),
|
||||
withPropsOnChange(
|
||||
['markers'],
|
||||
({ markers }) => ({
|
||||
markers: markers
|
||||
.map(({ ...markerProps, id }) => (
|
||||
<SimpleMarker
|
||||
key={id}
|
||||
id={id}
|
||||
{...markerProps}
|
||||
/>
|
||||
)),
|
||||
})
|
||||
)
|
||||
withPropsOnChange(['markers'], ({ markers }) => ({
|
||||
markers: markers.map(({ ...markerProps, id }) => (
|
||||
<SimpleMarker key={id} id={id} {...markerProps} />
|
||||
)),
|
||||
}))
|
||||
);
|
||||
|
||||
export default gMapHOC(gMapResizable);
|
||||
|
||||
@ -1,12 +1,16 @@
|
||||
/* eslint-disable react/prefer-stateless-function */
|
||||
import React, { Component } from 'react';
|
||||
import compose from 'recompose/compose';
|
||||
import { Link } from 'react-router';
|
||||
import defaultProps from 'recompose/defaultProps';
|
||||
import layoutStyles from './Layout.sass';
|
||||
// for hmr to work I need the first class to extend Component
|
||||
export class Layout extends Component { // eslint-disable-line
|
||||
export class Layout extends Component {
|
||||
// eslint-disable-line
|
||||
render() {
|
||||
const { styles: { layout, header, main, footer, logo, links } } = this.props;
|
||||
const {
|
||||
styles: { layout, header, main, footer, logo, links },
|
||||
} = this.props;
|
||||
return (
|
||||
<div className={layout}>
|
||||
<header className={header}>
|
||||
@ -32,7 +36,7 @@ export class Layout extends Component { // eslint-disable-line
|
||||
Ivan Starkov
|
||||
</a>
|
||||
</div>
|
||||
<div className={logo}></div>
|
||||
<div className={logo} />
|
||||
<div>
|
||||
<a href="https://twitter.com/icelabaratory">
|
||||
@icelabaratory
|
||||
|
||||
@ -1,14 +1,14 @@
|
||||
// file: main.jsx
|
||||
/* eslint-disable import/no-named-as-default */
|
||||
|
||||
import React from 'react';
|
||||
import { render } from 'react-dom';
|
||||
import { Router, Route, IndexRoute, browserHistory } from 'react-router';
|
||||
import 'normalize.css/normalize.css';
|
||||
import Layout from './Layout';
|
||||
import GMap from './GMap';
|
||||
import GMapLayers from './GMapLayers';
|
||||
import GMapOptim from './GMapOptim';
|
||||
import GMapResizable from './GMapResizable';
|
||||
|
||||
import 'normalize.css/normalize.css';
|
||||
import './Main.sass';
|
||||
|
||||
const mountNode = document.getElementById('app');
|
||||
@ -22,7 +22,6 @@ render(
|
||||
<Route markersCount={20} path="resizable" component={GMapResizable} />
|
||||
<IndexRoute markersCount={20} component={GMap} />
|
||||
</Route>
|
||||
</Router>
|
||||
,
|
||||
</Router>,
|
||||
mountNode
|
||||
);
|
||||
|
||||
@ -1,18 +1,17 @@
|
||||
import path from 'path'; // eslint-disable-line no-var
|
||||
import autoprefixer from 'autoprefixer'; // eslint-disable-line no-var
|
||||
import autoprefixer from 'autoprefixer'; // eslint-disable-line no-var
|
||||
import webpack from 'webpack';
|
||||
|
||||
export default {
|
||||
devtool: 'cheap-module-eval-source-map',
|
||||
postcss: [
|
||||
autoprefixer({ browsers: ['last 2 versions'] }),
|
||||
],
|
||||
postcss: [autoprefixer({ browsers: ['last 2 versions'] })],
|
||||
plugins: [
|
||||
new webpack.DefinePlugin(process.env.NODE_ENV
|
||||
? {
|
||||
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
|
||||
}
|
||||
: {}
|
||||
new webpack.DefinePlugin(
|
||||
process.env.NODE_ENV
|
||||
? {
|
||||
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
|
||||
}
|
||||
: {}
|
||||
),
|
||||
],
|
||||
module: {
|
||||
|
||||
@ -2,16 +2,20 @@ export const susolvkaCoords = { lat: 60.814305, lng: 47.051773 };
|
||||
|
||||
export const londonCoords = { lat: 51.508411, lng: -0.125364 };
|
||||
|
||||
export const generateMarkers = (count) =>
|
||||
[...Array(count)].fill(0) // fill(0) for loose mode
|
||||
.map((__, index) => ({
|
||||
id: index,
|
||||
lat: susolvkaCoords.lat +
|
||||
0.01 * index *
|
||||
export const generateMarkers = count =>
|
||||
[...Array(count)].fill(0).map((__, index) => ({
|
||||
// fill(0) for loose mode
|
||||
id: index,
|
||||
lat: susolvkaCoords.lat +
|
||||
0.01 *
|
||||
index *
|
||||
Math.sin(30 * Math.PI * index / 180) *
|
||||
Math.cos(50 * Math.PI * index / 180) + Math.sin(5 * index / 180),
|
||||
lng: susolvkaCoords.lng +
|
||||
0.01 * index *
|
||||
Math.cos(50 * Math.PI * index / 180) +
|
||||
Math.sin(5 * index / 180),
|
||||
lng: susolvkaCoords.lng +
|
||||
0.01 *
|
||||
index *
|
||||
Math.cos(70 + 23 * Math.PI * index / 180) *
|
||||
Math.cos(50 * Math.PI * index / 180) + Math.sin(5 * index / 180),
|
||||
}));
|
||||
Math.cos(50 * Math.PI * index / 180) +
|
||||
Math.sin(5 * index / 180),
|
||||
}));
|
||||
|
||||
@ -6,31 +6,30 @@ import pure from 'recompose/pure';
|
||||
import { Motion, spring } from 'react-motion';
|
||||
import clusterMarkerStyles from './ClusterMarker.sass';
|
||||
|
||||
export const clusterMarker = ({
|
||||
styles, text, hovered, $hover,
|
||||
defaultMotionStyle, motionStyle,
|
||||
}) => (
|
||||
<Motion
|
||||
defaultStyle={defaultMotionStyle}
|
||||
style={motionStyle}
|
||||
>
|
||||
export const clusterMarker = (
|
||||
{
|
||||
({ scale }) => (
|
||||
styles,
|
||||
text,
|
||||
hovered,
|
||||
$hover,
|
||||
defaultMotionStyle,
|
||||
motionStyle,
|
||||
}
|
||||
) => (
|
||||
<Motion defaultStyle={defaultMotionStyle} style={motionStyle}>
|
||||
{({ scale }) => (
|
||||
<div
|
||||
className={styles.marker}
|
||||
style={{
|
||||
transform: `translate3D(0,0,0) scale(${scale}, ${scale})`,
|
||||
zIndex: (hovered || $hover) ? 1 : 0,
|
||||
zIndex: hovered || $hover ? 1 : 0,
|
||||
}}
|
||||
>
|
||||
<div
|
||||
className={styles.text}
|
||||
>
|
||||
<div className={styles.text}>
|
||||
{text}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
)}
|
||||
</Motion>
|
||||
);
|
||||
|
||||
@ -49,29 +48,33 @@ export const clusterMarkerHOC = compose(
|
||||
// pure optimization can cause some effects you don't want,
|
||||
// don't use it in development for markers
|
||||
pure,
|
||||
withPropsOnChange(
|
||||
['initialScale'],
|
||||
({ initialScale, defaultScale, $prerender }) => ({
|
||||
initialScale,
|
||||
defaultMotionStyle: { scale: $prerender ? defaultScale : initialScale },
|
||||
})
|
||||
),
|
||||
withPropsOnChange(
|
||||
['hovered', '$hover'],
|
||||
({
|
||||
hovered, $hover, hoveredScale, defaultScale,
|
||||
stiffness, damping, precision,
|
||||
}) => ({
|
||||
$hover,
|
||||
hovered,
|
||||
motionStyle: {
|
||||
scale: spring(
|
||||
(hovered || $hover) ? hoveredScale : defaultScale,
|
||||
{ stiffness, damping, precision }
|
||||
),
|
||||
},
|
||||
})
|
||||
)
|
||||
withPropsOnChange(['initialScale'], ({
|
||||
initialScale,
|
||||
defaultScale,
|
||||
$prerender,
|
||||
}) => ({
|
||||
initialScale,
|
||||
defaultMotionStyle: { scale: $prerender ? defaultScale : initialScale },
|
||||
})),
|
||||
withPropsOnChange(['hovered', '$hover'], ({
|
||||
hovered,
|
||||
$hover,
|
||||
hoveredScale,
|
||||
defaultScale,
|
||||
stiffness,
|
||||
damping,
|
||||
precision,
|
||||
}) => ({
|
||||
$hover,
|
||||
hovered,
|
||||
motionStyle: {
|
||||
scale: spring(hovered || $hover ? hoveredScale : defaultScale, {
|
||||
stiffness,
|
||||
damping,
|
||||
precision,
|
||||
}),
|
||||
},
|
||||
}))
|
||||
);
|
||||
|
||||
export default clusterMarkerHOC(clusterMarker);
|
||||
|
||||
@ -1,26 +1,24 @@
|
||||
import React from 'react';
|
||||
import compose from 'recompose/compose';
|
||||
import SimpleMarker from './SimpleMarker';
|
||||
import stream2Props from '../utils/stream2Props';
|
||||
import 'rxjs/add/operator/filter';
|
||||
import 'rxjs/add/operator/map';
|
||||
import 'rxjs/add/operator/do';
|
||||
import 'rxjs/add/operator/scan';
|
||||
import 'rxjs/add/operator/distinctUntilChanged';
|
||||
import SimpleMarker from './SimpleMarker';
|
||||
import stream2Props from '../utils/stream2Props';
|
||||
|
||||
// import defaultProps from 'recompose/defaultProps';
|
||||
// import reactiveMarkerStyles from './reactiveMarker.scss';
|
||||
|
||||
export const reactiveMarker = (props) => (
|
||||
<SimpleMarker {...props} />
|
||||
);
|
||||
export const reactiveMarker = props => <SimpleMarker {...props} />;
|
||||
|
||||
export const reactiveMarkerHOC = compose(
|
||||
stream2Props(({ id, hoveredMarkerId$ }) => (
|
||||
stream2Props(({ id, hoveredMarkerId$ }) =>
|
||||
hoveredMarkerId$
|
||||
.map(hoveredMarkerId => hoveredMarkerId === id)
|
||||
.distinctUntilChanged()
|
||||
.map(v => ({ hovered: v }))
|
||||
))
|
||||
.map(v => ({ hovered: v })))
|
||||
);
|
||||
|
||||
export default reactiveMarkerHOC(reactiveMarker);
|
||||
|
||||
@ -4,31 +4,29 @@ import defaultProps from 'recompose/defaultProps';
|
||||
import getContext from 'recompose/getContext';
|
||||
// import mapPropsOnChange from 'recompose/mapPropsOnChange';
|
||||
import { Motion } from 'react-motion';
|
||||
import { clusterMarkerHOC } from './ClusterMarker.js';
|
||||
import { clusterMarkerHOC } from './ClusterMarker';
|
||||
import simpleMarkerStyles from './SimpleMarker.sass';
|
||||
|
||||
export const simpleMarker = ({
|
||||
styles, hovered, $hover,
|
||||
defaultMotionStyle, motionStyle,
|
||||
// hello,
|
||||
}) => (
|
||||
// console.log('hello', hello),
|
||||
<Motion
|
||||
defaultStyle={defaultMotionStyle}
|
||||
style={motionStyle}
|
||||
>
|
||||
export const simpleMarker = (
|
||||
{
|
||||
({ scale }) => (
|
||||
styles,
|
||||
hovered,
|
||||
$hover,
|
||||
defaultMotionStyle,
|
||||
motionStyle,
|
||||
// hello,
|
||||
} // console.log('hello', hello),
|
||||
) => (
|
||||
<Motion defaultStyle={defaultMotionStyle} style={motionStyle}>
|
||||
{({ scale }) => (
|
||||
<div
|
||||
className={styles.marker}
|
||||
style={{
|
||||
transform: `translate3D(0,0,0) scale(${scale}, ${scale})`,
|
||||
zIndex: (hovered || $hover) ? 1 : 0,
|
||||
zIndex: hovered || $hover ? 1 : 0,
|
||||
}}
|
||||
>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
/>
|
||||
)}
|
||||
</Motion>
|
||||
);
|
||||
|
||||
|
||||
@ -7,8 +7,7 @@ import 'rxjs/add/operator/distinctUntilChanged';
|
||||
describe('Playground', () => {
|
||||
it('Play', async () => {
|
||||
const comparator = (a, b) => a === b;
|
||||
const props$ = (new BehaviorSubject(1))
|
||||
.distinctUntilChanged(comparator);
|
||||
const props$ = new BehaviorSubject(1).distinctUntilChanged(comparator);
|
||||
|
||||
props$.subscribe(v => console.log(v)); // eslint-disable-line
|
||||
props$.next(1);
|
||||
|
||||
@ -3,8 +3,9 @@ import isReferentiallyTransparentFunctionComponent
|
||||
from './isReferentiallyTransparentFunctionComponent';
|
||||
|
||||
const createFactory = type => {
|
||||
const isReferentiallyTransparent =
|
||||
isReferentiallyTransparentFunctionComponent(type);
|
||||
const isReferentiallyTransparent = isReferentiallyTransparentFunctionComponent(
|
||||
type
|
||||
);
|
||||
return (p, c) =>
|
||||
createEagerElementUtil(false, isReferentiallyTransparent, type, p, c);
|
||||
};
|
||||
|
||||
@ -1,15 +1,17 @@
|
||||
const isClassComponent = Component => Boolean(
|
||||
Component &&
|
||||
Component.prototype &&
|
||||
typeof Component.prototype.isReactComponent === 'object'
|
||||
);
|
||||
const isClassComponent = Component =>
|
||||
Boolean(
|
||||
Component &&
|
||||
Component.prototype &&
|
||||
typeof Component.prototype.isReactComponent === 'object'
|
||||
);
|
||||
|
||||
const isReferentiallyTransparentFunctionComponent = Component => Boolean(
|
||||
typeof Component === 'function' &&
|
||||
!isClassComponent(Component) &&
|
||||
!Component.defaultProps &&
|
||||
!Component.contextTypes &&
|
||||
!Component.propTypes
|
||||
);
|
||||
const isReferentiallyTransparentFunctionComponent = Component =>
|
||||
Boolean(
|
||||
typeof Component === 'function' &&
|
||||
!isClassComponent(Component) &&
|
||||
!Component.defaultProps &&
|
||||
!Component.contextTypes &&
|
||||
!Component.propTypes
|
||||
);
|
||||
|
||||
export default isReferentiallyTransparentFunctionComponent;
|
||||
|
||||
@ -3,7 +3,7 @@ const omit = (obj, keys) => {
|
||||
const { ...rest } = obj;
|
||||
for (let i = 0; i < keys.length; i++) {
|
||||
const key = keys[i];
|
||||
if (rest.hasOwnProperty(key)) {
|
||||
if (key in rest) {
|
||||
delete rest[key];
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,7 +4,7 @@ const pick = (obj, keys) => {
|
||||
const result = {};
|
||||
for (let i = 0; i < keys.length; i++) {
|
||||
const key = keys[i];
|
||||
if (obj.hasOwnProperty(key)) {
|
||||
if (key in obj) {
|
||||
result[key] = obj[key];
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,16 +1,17 @@
|
||||
import { Component } from 'react';
|
||||
import createEagerFactory from './createEagerFactory';
|
||||
import createHelper from 'recompose/createHelper';
|
||||
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
|
||||
import 'rxjs/add/operator/distinctUntilChanged';
|
||||
import createEagerFactory from './createEagerFactory';
|
||||
import omit from './omit';
|
||||
|
||||
const prop2Stream = (propName, comparator = (a, b) => a === b) =>
|
||||
BaseComponent => {
|
||||
const factory = createEagerFactory(BaseComponent);
|
||||
return class extends Component {
|
||||
props$ = (new BehaviorSubject(this.props[propName]))
|
||||
.distinctUntilChanged(comparator);
|
||||
props$ = new BehaviorSubject(this.props[propName]).distinctUntilChanged(
|
||||
comparator
|
||||
);
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
this.props$.next(nextProps[propName]);
|
||||
|
||||
@ -2,12 +2,9 @@ const ptInSect = (x, a, b) => (x - a) * (x - b) <= 0;
|
||||
|
||||
export default ({ nw, se }, pt) => {
|
||||
const lngs = nw.lng < se.lng
|
||||
? [[nw.lng, se.lng]]
|
||||
: [[nw.lng, 180], [-180, se.lng]];
|
||||
? [[nw.lng, se.lng]]
|
||||
: [[nw.lng, 180], [-180, se.lng]];
|
||||
|
||||
|
||||
return (
|
||||
ptInSect(pt.lat, se.lat, nw.lat) &&
|
||||
lngs.some(([lngFrom, lngTo]) => ptInSect(pt.lng, lngFrom, lngTo))
|
||||
);
|
||||
return ptInSect(pt.lat, se.lat, nw.lat) &&
|
||||
lngs.some(([lngFrom, lngTo]) => ptInSect(pt.lng, lngFrom, lngTo));
|
||||
};
|
||||
|
||||
@ -1,18 +1,18 @@
|
||||
import { Component } from 'react';
|
||||
import createEagerFactory from './createEagerFactory';
|
||||
import createHelper from 'recompose/createHelper';
|
||||
import createEagerFactory from './createEagerFactory';
|
||||
|
||||
// if stream prop will change this will fail,
|
||||
// this is expected behavior
|
||||
const stream2Props = (props2Stream) =>
|
||||
const stream2Props = props2Stream =>
|
||||
BaseComponent => {
|
||||
const factory = createEagerFactory(BaseComponent);
|
||||
return class extends Component {
|
||||
state = {};
|
||||
|
||||
componentWillMount() {
|
||||
this.subscription = props2Stream(this.props)
|
||||
.subscribe(value => this.setState({ value }));
|
||||
this.subscription = props2Stream(this.props).subscribe(value =>
|
||||
this.setState({ value }));
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { Component } from 'react';
|
||||
import createEagerFactory from './createEagerFactory';
|
||||
import createHelper from 'recompose/createHelper';
|
||||
import createEagerFactory from './createEagerFactory';
|
||||
|
||||
const withStateSelector = (stateName, stateUpdaterName, selectorFactory) =>
|
||||
BaseComponent => {
|
||||
@ -11,13 +11,15 @@ const withStateSelector = (stateName, stateUpdaterName, selectorFactory) =>
|
||||
stateValue: this.selector(this.props),
|
||||
};
|
||||
|
||||
updateStateValue = (updateFn, callback) => (
|
||||
this.setState(({ stateValue }) => ({
|
||||
stateValue: typeof updateFn === 'function'
|
||||
? updateFn(stateValue)
|
||||
: updateFn,
|
||||
}), callback)
|
||||
);
|
||||
updateStateValue = (updateFn, callback) =>
|
||||
this.setState(
|
||||
({ stateValue }) => ({
|
||||
stateValue: typeof updateFn === 'function'
|
||||
? updateFn(stateValue)
|
||||
: updateFn,
|
||||
}),
|
||||
callback
|
||||
);
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
// reselect memoize result
|
||||
|
||||
38
package.json
38
package.json
@ -7,13 +7,17 @@
|
||||
"build:lib": "babel ./src -d lib",
|
||||
"build:umd": "webpack src/index_umd.js dist/GoogleMapReact.js --config webpack.config.dev.js",
|
||||
"build:umd:min": "webpack src/index_umd.js dist/GoogleMapReact.min.js --config webpack.config.prod.js",
|
||||
"build": "npm run build:lib && npm run build:umd && npm run build:umd:min",
|
||||
"build": "yarn run build:lib && yarn run build:umd && yarn run build:umd:min",
|
||||
"clean": "rimraf lib dist",
|
||||
"prepublish": "npm run clean && npm run build",
|
||||
"lint": "eslint src develop",
|
||||
"prepublish": "yarn run clean && yarn run build",
|
||||
"format": "prettier --trailing-comma es5 --single-quote --write 'src/**/*.js' 'src/**/*.js'",
|
||||
"format:dev": "prettier --trailing-comma es5 --single-quote --write 'develop/**/*.js' 'develop/**/*.js'",
|
||||
"lint": "eslint src",
|
||||
"lint:dev": "eslint develop",
|
||||
"test": "NODE_ENV=eee mocha --compilers js:babel-register --recursive --require babel-polyfill",
|
||||
"test:watch": "NODE_ENV=eee mocha --compilers js:babel-register --recursive --require babel-polyfill --watch",
|
||||
"start": "kotatsu serve --port 4000 --config ./develop/config/index.babel.js --presets es2015,stage-0,react,react-hmre ./develop/Main.js"
|
||||
"start": "kotatsu serve --port 4000 --config ./develop/config/index.babel.js --presets es2015,stage-0,react,react-hmre ./develop/Main.js",
|
||||
"precommit": "lint-staged"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@ -38,6 +42,7 @@
|
||||
},
|
||||
"homepage": "https://github.com/istarkov/google-map-react#readme",
|
||||
"peerDependencies": {
|
||||
"prop-types": "^15.5.6",
|
||||
"react": "^0.14.0 || ^15.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
@ -60,20 +65,27 @@
|
||||
"babel-preset-stage-0": "^6.5.0",
|
||||
"babel-register": "^6.14.0",
|
||||
"css-loader": "^0.23.1",
|
||||
"eslint": "^2.12.0",
|
||||
"eslint-config-airbnb": "^9.0.1",
|
||||
"eslint-plugin-import": "^1.8.1",
|
||||
"eslint-plugin-jsx-a11y": "^1.4.2",
|
||||
"eslint-plugin-react": "^5.1.1",
|
||||
"eslint": "^3.17.1",
|
||||
"eslint-config-airbnb": "^14.0.0",
|
||||
"eslint-config-prettier": "^1.5.0",
|
||||
"eslint-plugin-babel": "^4.1.1",
|
||||
"eslint-plugin-import": "^2.2.0",
|
||||
"eslint-plugin-jsx-a11y": "^4.0.0",
|
||||
"eslint-plugin-prettier": "^2.0.1",
|
||||
"eslint-plugin-react": "^6.8.0",
|
||||
"expect": "^1.11.1",
|
||||
"file-loader": "^0.8.5",
|
||||
"husky": "^0.13.3",
|
||||
"jsdom": "^6.5.1",
|
||||
"kotatsu": "^0.14.0",
|
||||
"lint-staged": "^3.4.0",
|
||||
"lodash": "^4.13.1",
|
||||
"mocha": "^2.3.3",
|
||||
"node-sass": "^3.7.0",
|
||||
"normalize.css": "^4.1.1",
|
||||
"postcss-loader": "^0.9.1",
|
||||
"prettier": "^0.22.0",
|
||||
"prop-types": "^15.5.6",
|
||||
"react": "^15.1.0",
|
||||
"react-addons-test-utils": "^15.1.0",
|
||||
"react-dom": "^15.1.0",
|
||||
@ -87,5 +99,11 @@
|
||||
"style-loader": "^0.13.1",
|
||||
"url-loader": "^0.5.7",
|
||||
"webpack": "^1.12.2"
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.js": [
|
||||
"prettier --trailing-comma es5 --single-quote --write",
|
||||
"git add"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@ -16,8 +16,7 @@ export default class GoogleMapMap extends Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div style={style} />
|
||||
);
|
||||
const { registerChild } = this.props;
|
||||
return <div ref={registerChild} style={style} />;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,7 @@
|
||||
import React, { PropTypes, Component } from 'react';
|
||||
/* eslint-disable react/forbid-prop-types */
|
||||
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import shallowEqual from 'fbjs/lib/shallowEqual';
|
||||
import omit from './utils/omit';
|
||||
|
||||
@ -44,7 +47,10 @@ export default class GoogleMapMarkers extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.props.dispatcher.on('kON_CHANGE', this._onChangeHandler);
|
||||
this.props.dispatcher.on('kON_MOUSE_POSITION_CHANGE', this._onMouseChangeHandler);
|
||||
this.props.dispatcher.on(
|
||||
'kON_MOUSE_POSITION_CHANGE',
|
||||
this._onMouseChangeHandler
|
||||
);
|
||||
this.props.dispatcher.on('kON_CLICK', this._onChildClick);
|
||||
this.props.dispatcher.on('kON_MDOWN', this._onChildMouseDown);
|
||||
|
||||
@ -65,12 +71,16 @@ export default class GoogleMapMarkers extends Component {
|
||||
);
|
||||
}
|
||||
|
||||
return !shallowEqual(this.props, nextProps) || !shallowEqual(this.state, nextState);
|
||||
return !shallowEqual(this.props, nextProps) ||
|
||||
!shallowEqual(this.state, nextState);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this.props.dispatcher.removeListener('kON_CHANGE', this._onChangeHandler);
|
||||
this.props.dispatcher.removeListener('kON_MOUSE_POSITION_CHANGE', this._onMouseChangeHandler);
|
||||
this.props.dispatcher.removeListener(
|
||||
'kON_MOUSE_POSITION_CHANGE',
|
||||
this._onMouseChangeHandler
|
||||
);
|
||||
this.props.dispatcher.removeListener('kON_CLICK', this._onChildClick);
|
||||
this.props.dispatcher.removeListener('kON_MDOWN', this._onChildMouseDown);
|
||||
|
||||
@ -94,9 +104,9 @@ export default class GoogleMapMarkers extends Component {
|
||||
state,
|
||||
() =>
|
||||
(state.children || []).length !== prevChildCount &&
|
||||
this._onMouseChangeHandler()
|
||||
this._onMouseChangeHandler()
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
_onChildClick = () => {
|
||||
if (this.props.onChildClick) {
|
||||
@ -107,7 +117,7 @@ export default class GoogleMapMarkers extends Component {
|
||||
this.props.onChildClick(hoverKey, childProps);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
_onChildMouseDown = () => {
|
||||
if (this.props.onChildMouseDown) {
|
||||
@ -118,8 +128,7 @@ export default class GoogleMapMarkers extends Component {
|
||||
this.props.onChildMouseDown(hoverKey, childProps);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
_onChildMouseEnter = (hoverKey, childProps) => {
|
||||
if (!this.dimesionsCache_) {
|
||||
@ -133,7 +142,7 @@ export default class GoogleMapMarkers extends Component {
|
||||
this.hoverChildProps_ = childProps;
|
||||
this.hoverKey_ = hoverKey;
|
||||
this.setState({ hoverKey });
|
||||
}
|
||||
};
|
||||
|
||||
_onChildMouseLeave = () => {
|
||||
if (!this.dimesionsCache_) {
|
||||
@ -152,25 +161,23 @@ export default class GoogleMapMarkers extends Component {
|
||||
this.hoverChildProps_ = null;
|
||||
this.setState({ hoverKey: null });
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
_onMouseAllow = (value) => {
|
||||
_onMouseAllow = value => {
|
||||
if (!value) {
|
||||
this._onChildMouseLeave();
|
||||
}
|
||||
|
||||
this.allowMouse_ = value;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
_onMouseChangeHandler = () => {
|
||||
if (this.allowMouse_) {
|
||||
this._onMouseChangeHandler_raf();
|
||||
this._onMouseChangeHandlerRaf();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
_onMouseChangeHandler_raf = () => { // eslint-disable-line
|
||||
_onMouseChangeHandlerRaf = () => {
|
||||
if (!this.dimesionsCache_) {
|
||||
return;
|
||||
}
|
||||
@ -184,21 +191,28 @@ export default class GoogleMapMarkers extends Component {
|
||||
React.Children.forEach(this.state.children, (child, childIndex) => {
|
||||
if (!child) return;
|
||||
// layers
|
||||
if (child.props.latLng === undefined &&
|
||||
child.props.lat === undefined &&
|
||||
child.props.lng === undefined) {
|
||||
if (
|
||||
child.props.latLng === undefined &&
|
||||
child.props.lat === undefined &&
|
||||
child.props.lng === undefined
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
const childKey = child.key !== undefined && child.key !== null ? child.key : childIndex;
|
||||
const dist = this.props.distanceToMouse(this.dimesionsCache_[childKey], mp, child.props);
|
||||
const childKey = child.key !== undefined && child.key !== null
|
||||
? child.key
|
||||
: childIndex;
|
||||
const dist = this.props.distanceToMouse(
|
||||
this.dimesionsCache_[childKey],
|
||||
mp,
|
||||
child.props
|
||||
);
|
||||
if (dist < hoverDistance) {
|
||||
distances.push(
|
||||
{
|
||||
key: childKey,
|
||||
dist,
|
||||
props: child.props,
|
||||
});
|
||||
distances.push({
|
||||
key: childKey,
|
||||
dist,
|
||||
props: child.props,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@ -218,79 +232,88 @@ export default class GoogleMapMarkers extends Component {
|
||||
} else {
|
||||
this._onChildMouseLeave();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
_getDimensions = (key) => {
|
||||
_getDimensions = key => {
|
||||
const childKey = key;
|
||||
return this.dimesionsCache_[childKey];
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const mainElementStyle = this.props.style || mainStyle;
|
||||
this.dimesionsCache_ = {};
|
||||
|
||||
const markers = React.Children.map(this.state.children, (child, childIndex) => {
|
||||
if (!child) return undefined;
|
||||
if (child.props.latLng === undefined &&
|
||||
const markers = React.Children.map(
|
||||
this.state.children,
|
||||
(child, childIndex) => {
|
||||
if (!child) return undefined;
|
||||
if (
|
||||
child.props.latLng === undefined &&
|
||||
child.props.lat === undefined &&
|
||||
child.props.lng === undefined) {
|
||||
return (
|
||||
React.cloneElement(child, {
|
||||
child.props.lng === undefined
|
||||
) {
|
||||
return React.cloneElement(child, {
|
||||
$geoService: this.props.geoService,
|
||||
$onMouseAllow: this._onMouseAllow,
|
||||
$prerender: this.props.prerender,
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
const latLng = child.props.latLng !== undefined
|
||||
? child.props.latLng
|
||||
: { lat: child.props.lat, lng: child.props.lng };
|
||||
|
||||
const pt = this.props.geoService.project(
|
||||
latLng,
|
||||
this.props.projectFromLeftTop
|
||||
);
|
||||
|
||||
const stylePtPos = {
|
||||
left: pt.x,
|
||||
top: pt.y,
|
||||
};
|
||||
|
||||
let dx = 0;
|
||||
let dy = 0;
|
||||
|
||||
if (!this.props.projectFromLeftTop) {
|
||||
// center projection
|
||||
if (this.props.geoService.hasSize()) {
|
||||
dx = this.props.geoService.getWidth() / 2;
|
||||
dy = this.props.geoService.getHeight() / 2;
|
||||
}
|
||||
}
|
||||
|
||||
// to prevent rerender on child element i need to pass
|
||||
// const params $getDimensions and $dimensionKey instead of dimension object
|
||||
const childKey = child.key !== undefined && child.key !== null
|
||||
? child.key
|
||||
: childIndex;
|
||||
|
||||
this.dimesionsCache_[childKey] = {
|
||||
x: pt.x + dx,
|
||||
y: pt.y + dy,
|
||||
...latLng,
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
key={childKey}
|
||||
style={{ ...style, ...stylePtPos }}
|
||||
className={child.props.$markerHolderClassName}
|
||||
>
|
||||
{React.cloneElement(child, {
|
||||
$hover: childKey === this.state.hoverKey,
|
||||
$getDimensions: this._getDimensions,
|
||||
$dimensionKey: childKey,
|
||||
$geoService: this.props.geoService,
|
||||
$onMouseAllow: this._onMouseAllow,
|
||||
$prerender: this.props.prerender,
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const latLng = child.props.latLng !== undefined
|
||||
? child.props.latLng
|
||||
: { lat: child.props.lat, lng: child.props.lng };
|
||||
|
||||
const pt = this.props.geoService.project(latLng, this.props.projectFromLeftTop);
|
||||
|
||||
const stylePtPos = {
|
||||
left: pt.x,
|
||||
top: pt.y,
|
||||
};
|
||||
|
||||
let dx = 0;
|
||||
let dy = 0;
|
||||
|
||||
if (!this.props.projectFromLeftTop) { // center projection
|
||||
if (this.props.geoService.hasSize()) {
|
||||
dx = this.props.geoService.getWidth() / 2;
|
||||
dy = this.props.geoService.getHeight() / 2;
|
||||
}
|
||||
}
|
||||
|
||||
// to prevent rerender on child element i need to pass
|
||||
// const params $getDimensions and $dimensionKey instead of dimension object
|
||||
const childKey = child.key !== undefined && child.key !== null ? child.key : childIndex;
|
||||
|
||||
this.dimesionsCache_[childKey] = {
|
||||
x: pt.x + dx,
|
||||
y: pt.y + dy,
|
||||
...latLng,
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
key={childKey}
|
||||
style={{ ...style, ...stylePtPos }}
|
||||
className={child.props.$markerHolderClassName}
|
||||
>
|
||||
{React.cloneElement(child, {
|
||||
$hover: childKey === this.state.hoverKey,
|
||||
$getDimensions: this._getDimensions,
|
||||
$dimensionKey: childKey,
|
||||
$geoService: this.props.geoService,
|
||||
$onMouseAllow: this._onMouseAllow,
|
||||
$prerender: this.props.prerender,
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
});
|
||||
);
|
||||
|
||||
return (
|
||||
<div style={mainElementStyle}>
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import React from 'react';
|
||||
import GoogleMapMarkers from './google_map_markers.js';
|
||||
import GoogleMapMarkers from './google_map_markers';
|
||||
|
||||
const style = {
|
||||
width: '50%',
|
||||
@ -13,7 +13,7 @@ const style = {
|
||||
// opacity: 0.3
|
||||
};
|
||||
|
||||
export default function (props) {
|
||||
export default function(props) {
|
||||
return (
|
||||
<div style={style}>
|
||||
<GoogleMapMarkers {...props} prerender />
|
||||
|
||||
@ -1 +1 @@
|
||||
export default from './google_map.js';
|
||||
export default from './google_map';
|
||||
|
||||
@ -1,2 +1,3 @@
|
||||
import GoogleMap from './google_map.js';
|
||||
import GoogleMap from './google_map';
|
||||
|
||||
module.exports = GoogleMap;
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
|
||||
export default function isArraysEqualEps(arrayA, arrayB, eps) {
|
||||
if (arrayA && arrayB) {
|
||||
for (let i = 0; i !== arrayA.length; ++i) {
|
||||
|
||||
@ -14,15 +14,21 @@ export default function detectBrowser() {
|
||||
let isChrome = navigator.userAgent.indexOf('Chrome') > -1;
|
||||
let isSafari = navigator.userAgent.indexOf('Safari') > -1;
|
||||
|
||||
if ((isChrome) && (isSafari)) {
|
||||
if (isChrome && isSafari) {
|
||||
isSafari = false;
|
||||
}
|
||||
|
||||
if ((isChrome) && (isOpera)) {
|
||||
if (isChrome && isOpera) {
|
||||
isChrome = false;
|
||||
}
|
||||
|
||||
detectBrowserResult_ = { isExplorer, isFirefox, isOpera, isChrome, isSafari };
|
||||
detectBrowserResult_ = {
|
||||
isExplorer,
|
||||
isFirefox,
|
||||
isOpera,
|
||||
isChrome,
|
||||
isSafari,
|
||||
};
|
||||
return detectBrowserResult_;
|
||||
}
|
||||
|
||||
|
||||
@ -10,38 +10,47 @@
|
||||
**/
|
||||
|
||||
// Reliable `window` and `document` detection
|
||||
var canUseDOM = !!(
|
||||
(typeof window !== 'undefined' &&
|
||||
window.document && window.document.createElement)
|
||||
);
|
||||
var canUseDOM = !!(typeof window !== 'undefined' &&
|
||||
window.document &&
|
||||
window.document.createElement);
|
||||
|
||||
// Check `document` and `window` in case of server-side rendering
|
||||
var _window
|
||||
var _window;
|
||||
if (canUseDOM) {
|
||||
_window = window
|
||||
_window = window;
|
||||
} else if (typeof self !== 'undefined') {
|
||||
_window = self
|
||||
_window = self;
|
||||
} else {
|
||||
_window = this
|
||||
_window = this;
|
||||
}
|
||||
|
||||
var attachEvent = typeof document !== 'undefined' && document.attachEvent;
|
||||
var stylesCreated = false;
|
||||
|
||||
if (canUseDOM && !attachEvent) {
|
||||
var requestFrame = (function(){
|
||||
var raf = _window.requestAnimationFrame || _window.mozRequestAnimationFrame || _window.webkitRequestAnimationFrame ||
|
||||
function(fn){ return _window.setTimeout(fn, 20); };
|
||||
return function(fn){ return raf(fn); };
|
||||
var requestFrame = (function() {
|
||||
var raf = _window.requestAnimationFrame ||
|
||||
_window.mozRequestAnimationFrame ||
|
||||
_window.webkitRequestAnimationFrame ||
|
||||
function(fn) {
|
||||
return _window.setTimeout(fn, 20);
|
||||
};
|
||||
return function(fn) {
|
||||
return raf(fn);
|
||||
};
|
||||
})();
|
||||
|
||||
var cancelFrame = (function(){
|
||||
var cancel = _window.cancelAnimationFrame || _window.mozCancelAnimationFrame || _window.webkitCancelAnimationFrame ||
|
||||
_window.clearTimeout;
|
||||
return function(id){ return cancel(id); };
|
||||
var cancelFrame = (function() {
|
||||
var cancel = _window.cancelAnimationFrame ||
|
||||
_window.mozCancelAnimationFrame ||
|
||||
_window.webkitCancelAnimationFrame ||
|
||||
_window.clearTimeout;
|
||||
return function(id) {
|
||||
return cancel(id);
|
||||
};
|
||||
})();
|
||||
|
||||
var resetTriggers = function(element){
|
||||
var resetTriggers = function(element) {
|
||||
var triggers = element.__resizeTriggers__,
|
||||
expand = triggers.firstElementChild,
|
||||
contract = triggers.lastElementChild,
|
||||
@ -54,20 +63,20 @@ if (canUseDOM && !attachEvent) {
|
||||
expand.scrollTop = expand.scrollHeight;
|
||||
};
|
||||
|
||||
var checkTriggers = function(element){
|
||||
var checkTriggers = function(element) {
|
||||
return element.offsetWidth != element.__resizeLast__.width ||
|
||||
element.offsetHeight != element.__resizeLast__.height;
|
||||
}
|
||||
element.offsetHeight != element.__resizeLast__.height;
|
||||
};
|
||||
|
||||
var scrollListener = function(e){
|
||||
var scrollListener = function(e) {
|
||||
var element = this;
|
||||
resetTriggers(this);
|
||||
if (this.__resizeRAF__) cancelFrame(this.__resizeRAF__);
|
||||
this.__resizeRAF__ = requestFrame(function(){
|
||||
this.__resizeRAF__ = requestFrame(function() {
|
||||
if (checkTriggers(element)) {
|
||||
element.__resizeLast__.width = element.offsetWidth;
|
||||
element.__resizeLast__.height = element.offsetHeight;
|
||||
element.__resizeListeners__.forEach(function(fn){
|
||||
element.__resizeListeners__.forEach(function(fn) {
|
||||
fn.call(element, e);
|
||||
});
|
||||
}
|
||||
@ -80,20 +89,24 @@ if (canUseDOM && !attachEvent) {
|
||||
keyframeprefix = '',
|
||||
animationstartevent = 'animationstart',
|
||||
domPrefixes = 'Webkit Moz O ms'.split(' '),
|
||||
startEvents = 'webkitAnimationStart animationstart oAnimationStart MSAnimationStart'.split(' '),
|
||||
pfx = '';
|
||||
startEvents = 'webkitAnimationStart animationstart oAnimationStart MSAnimationStart'.split(
|
||||
' '
|
||||
),
|
||||
pfx = '';
|
||||
|
||||
if(canUseDOM) {
|
||||
if (canUseDOM) {
|
||||
var elm = document.createElement('fakeelement');
|
||||
if( elm.style.animationName !== undefined ) { animation = true; }
|
||||
if (elm.style.animationName !== undefined) {
|
||||
animation = true;
|
||||
}
|
||||
|
||||
if( animation === false ) {
|
||||
for( var i = 0; i < domPrefixes.length; i++ ) {
|
||||
if( elm.style[ domPrefixes[i] + 'AnimationName' ] !== undefined ) {
|
||||
pfx = domPrefixes[ i ];
|
||||
if (animation === false) {
|
||||
for (var i = 0; i < domPrefixes.length; i++) {
|
||||
if (elm.style[domPrefixes[i] + 'AnimationName'] !== undefined) {
|
||||
pfx = domPrefixes[i];
|
||||
animationstring = pfx + 'Animation';
|
||||
keyframeprefix = '-' + pfx.toLowerCase() + '-';
|
||||
animationstartevent = startEvents[ i ];
|
||||
animationstartevent = startEvents[i];
|
||||
animation = true;
|
||||
break;
|
||||
}
|
||||
@ -102,16 +115,25 @@ if (canUseDOM && !attachEvent) {
|
||||
}
|
||||
|
||||
var animationName = 'resizeanim';
|
||||
var animationKeyframes = '@' + keyframeprefix + 'keyframes ' + animationName + ' { from { opacity: 0; } to { opacity: 0; } } ';
|
||||
var animationStyle = keyframeprefix + 'animation: 1ms ' + animationName + '; ';
|
||||
var animationKeyframes = '@' +
|
||||
keyframeprefix +
|
||||
'keyframes ' +
|
||||
animationName +
|
||||
' { from { opacity: 0; } to { opacity: 0; } } ';
|
||||
var animationStyle = keyframeprefix +
|
||||
'animation: 1ms ' +
|
||||
animationName +
|
||||
'; ';
|
||||
}
|
||||
|
||||
var createStyles = function() {
|
||||
if (!stylesCreated) {
|
||||
//opacity:0 works around a chrome bug https://code.google.com/p/chromium/issues/detail?id=286360
|
||||
var css = (animationKeyframes ? animationKeyframes : '') +
|
||||
'.resize-triggers { ' + (animationStyle ? animationStyle : '') + 'visibility: hidden; opacity: 0; } ' +
|
||||
'.resize-triggers, .resize-triggers > div, .contract-trigger:before { content: \" \"; display: block; position: absolute; top: 0; left: 0; height: 100%; width: 100%; overflow: hidden; } .resize-triggers > div { background: #eee; overflow: auto; } .contract-trigger:before { width: 200%; height: 200%; }',
|
||||
'.resize-triggers { ' +
|
||||
(animationStyle ? animationStyle : '') +
|
||||
'visibility: hidden; opacity: 0; } ' +
|
||||
'.resize-triggers, .resize-triggers > div, .contract-trigger:before { content: " "; display: block; position: absolute; top: 0; left: 0; height: 100%; width: 100%; overflow: hidden; } .resize-triggers > div { background: #eee; overflow: auto; } .contract-trigger:before { width: 200%; height: 200%; }',
|
||||
head = document.head || document.getElementsByTagName('head')[0],
|
||||
style = document.createElement('style');
|
||||
|
||||
@ -125,51 +147,64 @@ var createStyles = function() {
|
||||
head.appendChild(style);
|
||||
stylesCreated = true;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var addResizeListener = function(element, fn){
|
||||
var addResizeListener = function(element, fn) {
|
||||
if (element.parentNode === undefined) {
|
||||
var tempParentDiv = document.createElement('div');
|
||||
element.parentNode = tempParentDiv;
|
||||
}
|
||||
element = element.parentNode;
|
||||
if (attachEvent) element.attachEvent('onresize', fn);
|
||||
if (attachEvent)
|
||||
element.attachEvent('onresize', fn);
|
||||
else {
|
||||
if (!element.__resizeTriggers__) {
|
||||
if (getComputedStyle(element).position == 'static') element.style.position = 'relative';
|
||||
if (getComputedStyle(element).position == 'static')
|
||||
element.style.position = 'relative';
|
||||
createStyles();
|
||||
element.__resizeLast__ = {};
|
||||
element.__resizeListeners__ = [];
|
||||
(element.__resizeTriggers__ = document.createElement('div')).className = 'resize-triggers';
|
||||
(element.__resizeTriggers__ = document.createElement(
|
||||
'div'
|
||||
)).className = 'resize-triggers';
|
||||
element.__resizeTriggers__.innerHTML = '<div class="expand-trigger"><div></div></div>' +
|
||||
'<div class="contract-trigger"></div>';
|
||||
'<div class="contract-trigger"></div>';
|
||||
element.appendChild(element.__resizeTriggers__);
|
||||
resetTriggers(element);
|
||||
element.addEventListener('scroll', scrollListener, true);
|
||||
|
||||
/* Listen for a css animation to detect element display/re-attach */
|
||||
animationstartevent && element.__resizeTriggers__.addEventListener(animationstartevent, function(e) {
|
||||
if(e.animationName == animationName)
|
||||
resetTriggers(element);
|
||||
});
|
||||
animationstartevent &&
|
||||
element.__resizeTriggers__.addEventListener(
|
||||
animationstartevent,
|
||||
function(e) {
|
||||
if (e.animationName == animationName) resetTriggers(element);
|
||||
}
|
||||
);
|
||||
}
|
||||
element.__resizeListeners__.push(fn);
|
||||
}
|
||||
};
|
||||
|
||||
var removeResizeListener = function(element, fn){
|
||||
var removeResizeListener = function(element, fn) {
|
||||
element = element.parentNode;
|
||||
if (attachEvent) element.detachEvent('onresize', fn);
|
||||
if (attachEvent)
|
||||
element.detachEvent('onresize', fn);
|
||||
else {
|
||||
element.__resizeListeners__.splice(element.__resizeListeners__.indexOf(fn), 1);
|
||||
element.__resizeListeners__.splice(
|
||||
element.__resizeListeners__.indexOf(fn),
|
||||
1
|
||||
);
|
||||
if (!element.__resizeListeners__.length) {
|
||||
element.removeEventListener('scroll', scrollListener);
|
||||
element.__resizeTriggers__ = !element.removeChild(element.__resizeTriggers__);
|
||||
element.removeEventListener('scroll', scrollListener);
|
||||
element.__resizeTriggers__ = !element.removeChild(
|
||||
element.__resizeTriggers__
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
addResizeListener : addResizeListener,
|
||||
removeResizeListener : removeResizeListener
|
||||
addResizeListener: addResizeListener,
|
||||
removeResizeListener: removeResizeListener,
|
||||
};
|
||||
|
||||
@ -1,11 +1,10 @@
|
||||
import LatLng from './lib_geo/lat_lng.js';
|
||||
import Point from 'point-geometry';
|
||||
import Transform from './lib_geo/transform.js';
|
||||
|
||||
import LatLng from './lib_geo/lat_lng';
|
||||
import Transform from './lib_geo/transform';
|
||||
|
||||
export default class Geo {
|
||||
|
||||
constructor(tileSize) { // left_top view пользует гугл
|
||||
constructor(tileSize) {
|
||||
// left_top view пользует гугл
|
||||
// super();
|
||||
this.hasSize_ = false;
|
||||
this.hasView_ = false;
|
||||
@ -51,7 +50,8 @@ export default class Geo {
|
||||
project(ptLatLng, viewFromLeftTop) {
|
||||
if (viewFromLeftTop) {
|
||||
const pt = this.transform_.locationPoint(LatLng.convert(ptLatLng));
|
||||
pt.x -= this.transform_.worldSize * Math.round(pt.x / this.transform_.worldSize);
|
||||
pt.x -= this.transform_.worldSize *
|
||||
Math.round(pt.x / this.transform_.worldSize);
|
||||
|
||||
pt.x += this.transform_.width / 2;
|
||||
pt.y += this.transform_.height / 2;
|
||||
@ -81,12 +81,14 @@ export default class Geo {
|
||||
}
|
||||
|
||||
getBounds(margins, roundFactor) {
|
||||
const bndT = margins && margins[0] || 0;
|
||||
const bndR = margins && margins[1] || 0;
|
||||
const bndB = margins && margins[2] || 0;
|
||||
const bndL = margins && margins[3] || 0;
|
||||
const bndT = (margins && margins[0]) || 0;
|
||||
const bndR = (margins && margins[1]) || 0;
|
||||
const bndB = (margins && margins[2]) || 0;
|
||||
const bndL = (margins && margins[3]) || 0;
|
||||
|
||||
if (this.getWidth() - bndR - bndL > 0 && this.getHeight() - bndT - bndB > 0) {
|
||||
if (
|
||||
this.getWidth() - bndR - bndL > 0 && this.getHeight() - bndT - bndB > 0
|
||||
) {
|
||||
const topLeftCorner = this.unproject({
|
||||
x: bndL - this.getWidth() / 2,
|
||||
y: bndT - this.getHeight() / 2,
|
||||
@ -97,10 +99,14 @@ export default class Geo {
|
||||
});
|
||||
|
||||
let res = [
|
||||
topLeftCorner.lat, topLeftCorner.lng, // NW
|
||||
bottomRightCorner.lat, bottomRightCorner.lng, // SE
|
||||
bottomRightCorner.lat, topLeftCorner.lng, // SW
|
||||
topLeftCorner.lat, bottomRightCorner.lng, // NE
|
||||
topLeftCorner.lat,
|
||||
topLeftCorner.lng, // NW
|
||||
bottomRightCorner.lat,
|
||||
bottomRightCorner.lng, // SE
|
||||
bottomRightCorner.lat,
|
||||
topLeftCorner.lng, // SW
|
||||
topLeftCorner.lat,
|
||||
bottomRightCorner.lng, // NE
|
||||
];
|
||||
|
||||
if (roundFactor) {
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
|
||||
function isObjectLike(value) {
|
||||
return !!value && typeof value === 'object';
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
// source taken from https://github.com/rackt/redux/blob/master/src/utils/isPlainObject.js
|
||||
const fnToString = (fn) => Function.prototype.toString.call(fn);
|
||||
const fnToString = fn => Function.prototype.toString.call(fn);
|
||||
|
||||
/**
|
||||
* @param {any} obj The object to inspect.
|
||||
@ -20,7 +20,7 @@ export default function isPlainObject(obj) {
|
||||
|
||||
const constructor = proto.constructor;
|
||||
|
||||
return typeof constructor === 'function'
|
||||
&& constructor instanceof constructor
|
||||
&& fnToString(constructor) === fnToString(Object);
|
||||
return typeof constructor === 'function' &&
|
||||
constructor instanceof constructor &&
|
||||
fnToString(constructor) === fnToString(Object);
|
||||
}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { wrap } from './wrap.js';
|
||||
import { wrap } from './wrap';
|
||||
|
||||
export default class LatLng {
|
||||
static convert = (a) => {
|
||||
static convert = a => {
|
||||
if (a instanceof LatLng) {
|
||||
return a;
|
||||
}
|
||||
@ -15,7 +15,7 @@ export default class LatLng {
|
||||
}
|
||||
|
||||
return a;
|
||||
}
|
||||
};
|
||||
|
||||
constructor(lat, lng) {
|
||||
if (isNaN(lat) || isNaN(lng)) {
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
import LatLng from './lat_lng';
|
||||
|
||||
export default class LatLngBounds {
|
||||
static convert = (a) => {
|
||||
static convert = a => {
|
||||
if (!a || a instanceof LatLngBounds) return a;
|
||||
return new LatLngBounds(a);
|
||||
}
|
||||
};
|
||||
|
||||
constructor(sw, ne) {
|
||||
if (!sw) return;
|
||||
@ -49,23 +49,25 @@ export default class LatLngBounds {
|
||||
return this;
|
||||
}
|
||||
|
||||
getCenter = () => new LatLng(
|
||||
(this._sw.lat + this._ne.lat) / 2,
|
||||
(this._sw.lng + this._ne.lng) / 2)
|
||||
getCenter = () =>
|
||||
new LatLng(
|
||||
(this._sw.lat + this._ne.lat) / 2,
|
||||
(this._sw.lng + this._ne.lng) / 2
|
||||
);
|
||||
|
||||
getSouthWest = () => this._sw
|
||||
getSouthWest = () => this._sw;
|
||||
|
||||
getNorthEast = () => this._ne
|
||||
getNorthEast = () => this._ne;
|
||||
|
||||
getNorthWest = () => new LatLng(this.getNorth(), this.getWest())
|
||||
getNorthWest = () => new LatLng(this.getNorth(), this.getWest());
|
||||
|
||||
getSouthEast = () => new LatLng(this.getSouth(), this.getEast())
|
||||
getSouthEast = () => new LatLng(this.getSouth(), this.getEast());
|
||||
|
||||
getWest = () => this._sw.lng
|
||||
getWest = () => this._sw.lng;
|
||||
|
||||
getSouth = () => this._sw.lat
|
||||
getSouth = () => this._sw.lat;
|
||||
|
||||
getEast = () => this._ne.lng
|
||||
getEast = () => this._ne.lng;
|
||||
|
||||
getNorth = () => this._ne.lat
|
||||
getNorth = () => this._ne.lat;
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import LatLng from './lat_lng';
|
||||
/* eslint-disable class-methods-use-this */
|
||||
import Point from 'point-geometry';
|
||||
import { wrap } from './wrap.js';
|
||||
import LatLng from './lat_lng';
|
||||
import { wrap } from './wrap';
|
||||
|
||||
// A single transform, generally used for a single tile to be scaled, rotated, and zoomed.
|
||||
export default class Transform {
|
||||
@ -80,13 +81,15 @@ export default class Transform {
|
||||
project(latlng, worldSize) {
|
||||
return new Point(
|
||||
this.lngX(latlng.lng, worldSize),
|
||||
this.latY(latlng.lat, worldSize));
|
||||
this.latY(latlng.lat, worldSize)
|
||||
);
|
||||
}
|
||||
|
||||
unproject(point, worldSize) {
|
||||
return new LatLng(
|
||||
this.yLat(point.y, worldSize),
|
||||
this.xLng(point.x, worldSize));
|
||||
this.xLng(point.x, worldSize)
|
||||
);
|
||||
}
|
||||
|
||||
get x() {
|
||||
@ -108,7 +111,9 @@ export default class Transform {
|
||||
|
||||
// latitude to absolute y coord
|
||||
latY(lat, worldSize) {
|
||||
const y = 180 / Math.PI * Math.log(Math.tan(Math.PI / 4 + lat * Math.PI / 360));
|
||||
const y = 180 /
|
||||
Math.PI *
|
||||
Math.log(Math.tan(Math.PI / 4 + lat * Math.PI / 360));
|
||||
return (180 - y) * (worldSize || this.worldSize) / 360;
|
||||
}
|
||||
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
/* eslint-disable import/prefer-default-export */
|
||||
|
||||
export function wrap(n, min, max) {
|
||||
const d = max - min;
|
||||
return n === max ? n : ((n - min) % d + d) % d + min;
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
/* eslint-disable no-console */
|
||||
let $script_ = null;
|
||||
|
||||
let loadPromise_;
|
||||
@ -45,24 +46,27 @@ export default function googleMapLoader(bootstrapURLKeys) {
|
||||
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
if (Object.keys(bootstrapURLKeys).indexOf('callback') > -1) {
|
||||
console.error('"callback" key in bootstrapURLKeys is not allowed, ' + // eslint-disable-line
|
||||
'use onGoogleApiLoaded property instead');
|
||||
throw new Error('"callback" key in bootstrapURLKeys is not allowed, ' +
|
||||
'use onGoogleApiLoaded property instead');
|
||||
console.error(
|
||||
'"callback" key in bootstrapURLKeys is not allowed, ' + // eslint-disable-line
|
||||
'use onGoogleApiLoaded property instead'
|
||||
);
|
||||
throw new Error(
|
||||
'"callback" key in bootstrapURLKeys is not allowed, ' +
|
||||
'use onGoogleApiLoaded property instead'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const queryString = Object.keys(bootstrapURLKeys)
|
||||
.reduce(
|
||||
(r, key) => `${r}&${key}=${bootstrapURLKeys[key]}`,
|
||||
''
|
||||
);
|
||||
const queryString = Object.keys(bootstrapURLKeys).reduce(
|
||||
(r, key) => `${r}&${key}=${bootstrapURLKeys[key]}`,
|
||||
''
|
||||
);
|
||||
|
||||
$script_(
|
||||
`https://maps.googleapis.com/maps/api/js?callback=_$_google_map_initialize_$_${queryString}`,
|
||||
() =>
|
||||
typeof window.google === 'undefined' &&
|
||||
reject(new Error('google map initialization error (not loaded)'))
|
||||
reject(new Error('google map initialization error (not loaded)'))
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@ -1,6 +1,3 @@
|
||||
|
||||
const log2 = Math.log2
|
||||
? Math.log2
|
||||
: (x) => Math.log(x) / Math.LN2;
|
||||
const log2 = Math.log2 ? Math.log2 : x => Math.log(x) / Math.LN2;
|
||||
|
||||
export default log2;
|
||||
|
||||
@ -3,7 +3,7 @@ const omit = (obj, keys) => {
|
||||
const { ...rest } = obj;
|
||||
for (let i = 0; i < keys.length; i++) {
|
||||
const key = keys[i];
|
||||
if (rest.hasOwnProperty(key)) {
|
||||
if (key in rest) {
|
||||
delete rest[key];
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,10 +1,13 @@
|
||||
// source taken from https://github.com/rackt/redux/blob/master/src/utils/pick.js
|
||||
|
||||
export default function pick(obj, fn) {
|
||||
return Object.keys(obj).reduce((result, key) => {
|
||||
if (fn(obj[key])) {
|
||||
result[key] = obj[key]; // eslint-disable-line
|
||||
}
|
||||
return result;
|
||||
}, {});
|
||||
return Object.keys(obj).reduce(
|
||||
(result, key) => {
|
||||
if (fn(obj[key])) {
|
||||
result[key] = obj[key]; // eslint-disable-line
|
||||
}
|
||||
return result;
|
||||
},
|
||||
{}
|
||||
);
|
||||
}
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
|
||||
export default function raf(callback) {
|
||||
if (window.requestAnimationFrame) {
|
||||
return window.requestAnimationFrame(callback);
|
||||
}
|
||||
|
||||
const nativeRaf = window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame;
|
||||
const nativeRaf = window.webkitRequestAnimationFrame ||
|
||||
window.mozRequestAnimationFrame;
|
||||
|
||||
return nativeRaf
|
||||
? nativeRaf(callback)
|
||||
|
||||
@ -1,16 +1,15 @@
|
||||
const GOOGLE_TILE_SIZE = 256;
|
||||
import log2 from './math/log2';
|
||||
|
||||
const GOOGLE_TILE_SIZE = 256;
|
||||
|
||||
function latLng2World({ lat, lng }) {
|
||||
const sin = Math.sin(lat * Math.PI / 180);
|
||||
const x = (lng / 360 + 0.5);
|
||||
let y = (0.5 - 0.25 * Math.log((1 + sin) / (1 - sin)) / Math.PI);
|
||||
const x = lng / 360 + 0.5;
|
||||
let y = 0.5 - 0.25 * Math.log((1 + sin) / (1 - sin)) / Math.PI;
|
||||
|
||||
y = y < 0 // eslint-disable-line
|
||||
? 0
|
||||
: y > 1
|
||||
? 1
|
||||
: y;
|
||||
: y > 1 ? 1 : y;
|
||||
return { x, y };
|
||||
}
|
||||
|
||||
@ -20,7 +19,7 @@ function world2LatLng({ x, y }) {
|
||||
// TODO test that this is faster
|
||||
// 360 * Math.atan(Math.exp((180 - y * 360) * Math.PI / 180)) / Math.PI - 90;
|
||||
return {
|
||||
lat: (180 / Math.PI * Math.atan(0.5 * (Math.exp(n) - Math.exp(-n)))),
|
||||
lat: 180 / Math.PI * Math.atan(0.5 * (Math.exp(n) - Math.exp(-n))),
|
||||
lng: x * 360 - 180,
|
||||
};
|
||||
}
|
||||
@ -28,15 +27,20 @@ function world2LatLng({ x, y }) {
|
||||
// Thank you wiki https://en.wikipedia.org/wiki/Geographic_coordinate_system
|
||||
function latLng2MetersPerDegree({ lat }) {
|
||||
const phi = lat * Math.PI / 180;
|
||||
const metersPerLatDegree = 111132.92 - 559.82 * Math.cos(2 * phi) +
|
||||
1.175 * Math.cos(4 * phi) - 0.0023 * Math.cos(6 * phi);
|
||||
const metersPerLatDegree = 111132.92 -
|
||||
559.82 * Math.cos(2 * phi) +
|
||||
1.175 * Math.cos(4 * phi) -
|
||||
0.0023 * Math.cos(6 * phi);
|
||||
const metersPerLngDegree = 111412.84 * Math.cos(phi) -
|
||||
93.5 * Math.cos(3 * phi) + 0.118 * Math.cos(5 * phi);
|
||||
93.5 * Math.cos(3 * phi) +
|
||||
0.118 * Math.cos(5 * phi);
|
||||
return { metersPerLatDegree, metersPerLngDegree };
|
||||
}
|
||||
|
||||
function meters2LatLngBounds(meters, { lat, lng }) {
|
||||
const { metersPerLatDegree, metersPerLngDegree } = latLng2MetersPerDegree({ lat });
|
||||
const { metersPerLatDegree, metersPerLngDegree } = latLng2MetersPerDegree({
|
||||
lat,
|
||||
});
|
||||
|
||||
const latDelta = 0.5 * meters / metersPerLatDegree;
|
||||
const lngDelta = 0.5 * meters / metersPerLngDegree;
|
||||
@ -69,7 +73,7 @@ function fitNwSe(nw, se, width, height) {
|
||||
const seWorld = latLng2World(se);
|
||||
const dx = nwWorld.x < seWorld.x
|
||||
? seWorld.x - nwWorld.x
|
||||
: (1 - nwWorld.x) + seWorld.x;
|
||||
: 1 - nwWorld.x + seWorld.x;
|
||||
const dy = seWorld.y - nwWorld.y;
|
||||
|
||||
if (dx <= 0 && dy <= 0) {
|
||||
@ -85,8 +89,8 @@ function fitNwSe(nw, se, width, height) {
|
||||
x: nwWorld.x < seWorld.x // eslint-disable-line
|
||||
? 0.5 * (nwWorld.x + seWorld.x)
|
||||
: nwWorld.x + seWorld.x - 1 > 0
|
||||
? 0.5 * (nwWorld.x + seWorld.x - 1)
|
||||
: 0.5 * (1 + nwWorld.x + seWorld.x),
|
||||
? 0.5 * (nwWorld.x + seWorld.x - 1)
|
||||
: 0.5 * (1 + nwWorld.x + seWorld.x),
|
||||
y: 0.5 * (nwWorld.y + seWorld.y),
|
||||
};
|
||||
|
||||
@ -179,10 +183,10 @@ export function meters2ScreenPixels(meters, { lat, lng }, zoom) {
|
||||
export function tile2LatLng({ x, y }, zoom) {
|
||||
const n = Math.PI - 2 * Math.PI * y / Math.pow(2, zoom);
|
||||
|
||||
return ({
|
||||
lat: (180 / Math.PI * Math.atan(0.5 * (Math.exp(n) - Math.exp(-n)))),
|
||||
lng: (x / Math.pow(2, zoom) * 360 - 180),
|
||||
});
|
||||
return {
|
||||
lat: 180 / Math.PI * Math.atan(0.5 * (Math.exp(n) - Math.exp(-n))),
|
||||
lng: x / Math.pow(2, zoom) * 360 - 180,
|
||||
};
|
||||
}
|
||||
|
||||
export function latLng2Tile({ lat, lng }, zoom) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user