UNPKG

7.01 kBMarkdownView Raw
1# Documentation
2
3Here I'll try to explain why some methods in google map react are needed and how to use them.
4
5For all examples I'll use [recompose](github.com/acdlite/recompose)
6and you must have basic understanding what `css-modules` is.
7
8_Looks like to rewrite current api I need to create Documentation about current version,
9so it will be easier to detect wrong ideas and solutions_
10
11## Simple example.
12
13[Simple example](http://www.webpackbin.com/N1N_45Owz)
14
15At `Map.js` you will see the smallest possible boilerplate for GoogleMapReact component,
16
17And a `MyMarker.js` is a simple React component.
18
19Open `Log` tab at the top of `webpackbin` and see the `mapProps` log.
20(_see the `withProps` at `Map.js`_)
21
22First value is the { `center` and `zoom` } which is set by you (_see withState at Map.js_),
23and second value is the value provided by `GoogleMapReact` component at initialization in `onChange` callback.
24
25```javascript
26{
27 center: { lat, lng }, // current map center
28 zoom: 4, // current map zoom
29 bounds: { nw, se, sw... }, // map corners in lat lng
30 size: { width, height... } // map size in px
31}
32```
33
34Calling `onChange` at initialization is needed because `map bounds` can't be calculated without knowledge of map size,
35and bounds are really usefull in a lot of situations. (_see Note below_)
36
37Please move and zoom the map to see log changes.
38
39Be sure that `onChange` callback is not called at realtime, and only at `idle` google map api callback.
40
41It's because google api itself provides changes with some delay and to avoid synchronization issues
42one of the ways was to use `idle` callback.
43
44On creation map uses the space of parent container and if parent container has zero height or width
45the map will be not visible. (_This is one of the most common issue_)
46
47If you want to place map inside `display: flex` container you need to pass `style` property
48with `{ flex: 1 }` to the control as like as [here](https://github.com/google-map-react/google-map-thousands-markers/blob/master/src/Map.js#L32)
49
50By default map will not raise `onChange` event if parent size has changed, to change such behavior
51add `resetBoundsOnResize = {true}` property.
52
53_NOTE: Now I think it was wrong decision to call onChange at initialization.
54In the future releases
55I'll remove such behavior and will provide helper to calculate size and bounds outside map control.
56I think about helper similar to [AutoSizer](https://github.com/bvaughn/react-virtualized/blob/master/docs/AutoSizer.md)
57it also will allow to remove `resetBoundsOnResize`, `style` properties_
58
59PS: I highly recommend you to use GoogleMapReact as a controllable component,
60and always provide `center`, `zoom` and `onChange` props. (_see withState_)
61
62_NOTE: In the future releases I'll remove usage of all `defaultProps` like `defaultCenter`_
63
64## Whats wrong with "Simple example" above
65
66The wrong part is that React components are placed on the map positioning from top, left corner.
67
68In most cases it's not the expected behaviour, so we need to change the MyMarker position by changing
69it's `position` and `left`, `top` css properties, or use `flex` as like as in this example.
70
71[Good position](http://www.webpackbin.com/VJBKkj_vM)
72
73Now `MyMarker` centered well, see the `myMarker.css` css changes and `MyMarker.js` layout change.
74
75## Few markers with hover example.
76
77[Few markers with hover example](http://www.webpackbin.com/Ny9EW1cwf)
78
79As we use ordinary React components we can use any methods we use for hover effects like
80- css
81- onMouseEnter, onMouseLeave
82
83But the problem you will see in example that markers are uniformly distributed over the map only in
84designer pictures. In real life all that markers will be possibly in one place ;-)
85
86And with ordinary hovers we have the problem, it's hard and sometimes impossible to hover on some markers.
87So the solution is to use some algorithm for hovering.
88
89(_Note: but I think there are a lot of cases exists there you can use ordinary hovers without any issues.
90Yes, sometimes real life is like a magazine picture_)
91
92## Few markers with hover example done right.
93
94[Few markers with hover example done right](http://www.webpackbin.com/N1Cmhy5wf)
95
96Now markers are hoverable even if placed under other marker.
97
98Let's see what has changed,
99- I've added four properties to map control `distanceToMouse`, `hoverDistance`, `onChildMouseEnter`, `onChildMouseLeave`
100- Instead of using css hovers, I now pass `hover` property to marker directly.
101
102So what does that properties means.
103
104- `distanceToMouse` you need to pass a distance function which will compute distance based on mouse position,
105marker position, and any other properties you want.
106
107 It can be non euclidean distance based on some of your internals.
108 For example you can return a smaller distance for some markers making them more hoverable,
109 or to return infinite distance for other markers making them unhoverable.
110
111 For circle markers of equal radius it can be euclidean distance
112
113 ```javascript
114 function distanceToMouse({ x, y }, { x: mouseX, y: mouseY }) {
115 return Math.sqrt((x - mouseX) * (x - mouseX) + (y - mouseY) * (y - mouseY))
116 }
117 ```
118
119 At the example above I use some kind of rectangular distance.
120
121 [Other distanceToMouse example](https://github.com/google-map-react/old-examples/blob/dbfc2fcd381cc39da315875f5a45d4ebee765f26/web/flux/components/examples/x_distance_hover/distance_hover_map_page.jsx#L31-L46)
122
123
124- `hoverDistance: number` distance threshold,
125system can decide that marker is hovered only if `distanceToMouse` for that marker returns value less than this threshold.
126
127- `onChildMouseEnter` - similar to `onMouseEnter` but here it's a callback called with `key` and `props` arguments for marker which have the smallest `distanceToMouse` value below `hoverDistance` threshold.
128
129- `onChildMouseLeave` - similar to `onMouseLeave`.
130
131Be sure that `onChildMouseEnter`, `onChildMouseLeave` and any other method starting with `onChild*` are useless without `hoverDistance` and `distanceToMouse` props.
132
133And even now system uses some defaults for both `distanceToMouse` and `hoverDistance` it's not a good idea to use them for your app.
134
135Other `onChild*` methods `onChildClick`, `onChildMouseDown`, `onChildMouseUp`, `onChildMouseMove`.
136
137(_`onChildMouseDown`, `onChildMouseUp`, `onChildMouseMove` are usefull for creating draggable markers,
138to prevent map from moving when you drag something over, you can set `draggable` map property to false
139_)
140
141(_Note: defaults for `distanceToMouse` and `hoverDistance` will be removed in future releases_)
142
143
144### Helper utilities
145
146```javascript
147import { meters2ScreenPixels } from 'google-map-react/utils';
148const { w, h } = meters2ScreenPixels(sizeInMeters, { lat, lng } /* marker coords*/, zoom /* map zoom*/);
149```
150
151`meters2ScreenPixels` it returns `horizontal - w` and `vertical - h` sizes for given size in meters, point and zoom.
152
153Having the mercator map projection for some places w and h will be different, for most places almost the same.
154
155
156## To be continued