From 583cecd0a4e50f1f959bfe55f5f6d3f1b60fe310 Mon Sep 17 00:00:00 2001 From: Ib Green Date: Tue, 29 May 2018 11:54:16 -0700 Subject: [PATCH] reuseMap prop now applies styles. Markdown cleanup (#517) --- docs/components/interactive-map.md | 41 +++++++++++--- docs/components/static-map.md | 90 ++++++++++++++++-------------- docs/whats-new.md | 5 +- examples/reuse-map/src/app.js | 24 ++++++-- examples/reuse-map/src/bart-map.js | 21 ++++--- src/mapbox/mapbox.js | 10 +++- 6 files changed, 123 insertions(+), 68 deletions(-) diff --git a/docs/components/interactive-map.md b/docs/components/interactive-map.md index 7636523a..b1687616 100644 --- a/docs/components/interactive-map.md +++ b/docs/components/interactive-map.md @@ -32,56 +32,71 @@ class Map extends Component { Has all properties of [StaticMap](/docs/components/static-map.md) and the following: ##### `onViewportChange` {Function} -Callback that is fired when the user interacted with the map. -The object passed to the callback contains viewport properties such as -`longitude`, `latitude`, `zoom` etc. -If the map is intended to be interactive, the app use this prop to listen to -map updates and update the props accordingly. +Callback that is fired when the user interacted with the map. + +`onViewportChange(viewState)` + +The object passed to the callback contains viewport properties such as `longitude`, `latitude`, `zoom` etc. + +Note: +* Even if the newer `onViewStateChange` callback is supplied, the `onViewportChange` callback will still be called if supplied. ##### `maxZoom` {Number} [default: 20] + Max zoom level. ##### `minZoom` {Number} [default: 0] + Min zoom level. ##### `maxPitch` {Number} [default: 60] + Max pitch in degrees. ##### `minPitch` {Number} [default: 0] + Min pitch in degrees. ##### `scrollZoom` {Bool} [default: true] + Enable croll to zoom. ##### `dragPan` {Bool} [default: true] + Enable drag to pan. ##### `dragRotate` {Bool} [default: true] + Enable drag to rotate. ##### `doubleClickZoom` {Bool} [default: true] + Enable double click to zoom. ##### `touchZoom` {Bool} [default: true] + Enable multitouch zoom. ##### `touchRotate` {Bool} [default: false] + Enable multitouch rotate. ##### `clickRadius` {Number} [default: 0] + Radius to detect features around a clicked point. ##### `mapControls` {Object} -A map control instance to replace the default map controls. -This object must implement the following interface: +A map control instance to replace the default map controls. + +This object must implement the following interface: - `events` - An array of subscribed events - `handleEvent(event, context)` - A method that handles interactive events ##### `visibilityConstraints` {Object} ==EXPERIMENTAL== -An object with the bounding `minZoom`, `maxZoom`, `minPitch`, `maxPitch` within -which the map should be visible. This will manage automatically toggling the + +An object with the bounding `minZoom`, `maxZoom`, `minPitch`, `maxPitch` within which the map should be visible. This will manage automatically toggling the `visible` prop in `StaticMap`. Parameters @@ -92,6 +107,7 @@ Parameters To make a layer interactive, set the `interactive` property in the layer style to `true`. ##### `onHover` {Function} + Called when the map is hovered over. Parameters @@ -102,6 +118,7 @@ Parameters To make a layer interactive, set the `interactive` property in the layer style to `true`. ##### `onClick` {Function} + Called when the map is clicked. Parameters @@ -112,6 +129,7 @@ Parameters To make a layer interactive, set the `interactive` property in the layer style to `true`. ##### `getCursor` {Function} + Accessor that returns a cursor style to show interactive state. Called when the component is being rendered. Parameters @@ -120,9 +138,11 @@ Parameters + `state.isHovering` - If the pointer is over a clickable feature. ##### `transitionDuration` {Number} + Duration of transition in milliseconds. If specified, the map's viewport will smoothly move from the previous props to the current one. Default `0`; ##### `transitionInterpolator` {Object} + An interpolator object that defines the transition behavior between two map states. `react-map-gl` offers two interpolators: - `LinearInterpolator` - similar to Mapbox's `easeTo` behavior. - `FlyToInterpolator` - similar to Mapbox's `flyTo` behavior. @@ -139,9 +159,11 @@ Default: `new LinearInterpolator()` For details about using transition interpolators, see [transitions](/docs/advanced/viewport-transitions.md). ##### `transitionEasing` {Function} + Easing function that maps a value from `[0, 1]` to `[0, 1]`. Default to `t => t` (linear). Check out [http://easings.net/](http://easings.net/) for common easing curves. ##### `transitionInterruption` {Number} + What to do if an ongoing transition is interrupted by another transition. There are 3 options: - `TRANSITION_EVENTS.BREAK` - Start new transition from the current view. This is the default. - `TRANSITION_EVENTS.SNAP_TO_END` - Jump to the end of the previous transition before starting the new transition. @@ -157,6 +179,7 @@ import {TRANSITION_EVENTS} from 'react-map-gl'; Callback that is fired when a transition is triggered. ##### `onTransitionInterrupt` {Function} + Callback that is fired when an ongoing transition is interrupted by another transition. ##### `onTransitionEnd` {Function} diff --git a/docs/components/static-map.md b/docs/components/static-map.md index 586ec082..2caa0d25 100644 --- a/docs/components/static-map.md +++ b/docs/components/static-map.md @@ -25,10 +25,12 @@ class Map extends Component { ## Properties ##### `mapboxApiAccessToken` {String} + Mapbox API access token for `MapboxGL`. Required when using Mapbox vector tiles/styles Mapbox WebGL context creation option. Useful when you want to export the canvas as a PNG ##### `mapStyle` {String | Object | Immutable.Map} + The Mapbox style. A string url or a [MapboxGL style](https://www.mapbox.com/mapbox-gl-style-spec/#layer-interactive) object (regular JS object or Immutable.Map). @@ -51,92 +53,94 @@ An object containing the view state of the map specified by the following fields * `pitch` {Number} - default: `0` - The pitch of the viewport. * `altitude` {Number} - default: `1.5 screen heights` -Note: Either the viewState, or the `latitude`, `longitude` and `zoom` properties need to be specified. +Note: Either the `viewState`, or the `latitude`, `longitude` and `zoom` properties need to be specified. ##### `latitude` {Number} -The latitude of the center of the map. + +The latitude of the center of the map, as a top level prop. Only used if `viewState` is not supplied. ##### `longitude` {Number} -The longitude of the center of the map. + +The longitude of the center of the map, as a top level prop. Only used if `viewState` is not supplied. ##### `zoom` {Number} -The tile zoom level of the map. Bounded implicitly by default `minZoom` -and `maxZoom` of `MapboxGL`. + +The tile zoom level of the map, as a top level prop. Only used if `viewState` is not supplied. + +Bounded implicitly by default `minZoom` and `maxZoom` of `MapboxGL` ##### `bearing` {Number} - default: `0` -Specify the bearing of the viewport. + +Specify the bearing of the viewport, as a top level prop. Only used if `viewState` is not supplied.. ##### `pitch` {Number} - default: `0` -Specify the pitch of the viewport. + +Specify the pitch of the viewport, as a top level prop. Only used if `viewState` is not supplied.. ##### `altitude` {Number} - default: `1.5 (screen heights)` + +> Non-public API, see https://github.com/mapbox/mapbox-gl-js/issues/1137. + Altitude of the viewport camera. -Note: Non-public API, see https://github.com/mapbox/mapbox-gl-js/issues/1137. ##### `visible` {Bool} - default: `true` -Whether the map is visible. -Unmounting and re-mounting a Mapbox instance is known to be costly. -This option offers a way to hide a map using CSS style. + +Whether the map is visible. Unmounting and re-mounting a Mapbox instance is known to be costly. This option offers a way to hide a map using CSS style. ##### `preserveDrawingBuffer` {Bool} - default: `false` -Equivalent to Mapbox's `preserveDrawingBuffer` -[option](https://www.mapbox.com/mapbox-gl-js/api/#map). -If `true`, the map's canvas can be exported to a PNG using `map.getCanvas().toDataURL()`. + +Equivalent to Mapbox's `preserveDrawingBuffer` [option](https://www.mapbox.com/mapbox-gl-js/api/#map). If `true`, the map's canvas can be exported to a PNG using `map.getCanvas().toDataURL()`. ##### `attributionControl` {Bool} - default: `true` -Equivalent to Mapbox's `attributionControl` -[option](https://www.mapbox.com/mapbox-gl-js/api/#map). -If `true`, shows Mapbox's attribution control. + +Equivalent to Mapbox's `attributionControl` [option](https://www.mapbox.com/mapbox-gl-js/api/#map). If `true`, shows Mapbox's attribution control. ##### `preventStyleDiffing` {Bool} - default: `false` -If `mapStyle` is assigned an Immutable object, when the prop changes, `StaticMap` can diff -between the two values and call the appropriate Mapbox API such as `addLayer`, -`removeLayer`, `setStyle`, `setData`, etc. -This allows apps to update data sources and layer styles efficiently. -In use cases such as animation or dynamic showing/hiding layers, style diffing prevents the -map from reloading and flickering when the map style changes. + +If `mapStyle` is assigned an Immutable object, when the prop changes, `StaticMap` can diff between the two values and call the appropriate Mapbox API such as `addLayer`, `removeLayer`, `setStyle`, `setData`, etc. +This allows apps to update data sources and layer styles efficiently. In use cases such as animation or dynamic showing/hiding layers, style diffing prevents the map from reloading and flickering when the map style changes. There are known issues with style diffing. As stopgap, use this option to prevent style diffing. ##### `reuseMaps` {Bool} - default: `false` -** This prop is experimental. ** + +> This prop is experimental. If `true`, when the map component is unmounted, instead of calling `remove` on the Mapbox map instance, save it for later reuse. This will avoid repeatedly creating new Mapbox map instances if possible. Applications that frequently mount and unmount maps may try this prop to help work around a mapbox-gl resource leak issue that can lead to a browser crash in certain situations. +##### `transformRequest` {Function} - default: `null` + +A callback run before the Map makes a request for an external URL. The callback can be used to modify the url, set headers, or set the credentials property for cross-origin requests. +Expected to return an object with a `url` property and optionally `headers` and `credentials` properties. Equivalent to Mapbox's `transformRequest` [map option](https://www.mapbox.com/mapbox-gl-js/api#map). + +## Callbacks + ##### `onLoad` {Function} - default: `no-op function` -A callback run when the map emits a `load` event. -[Mapbox docs](https://www.mapbox.com/mapbox-gl-js/api#map.event:load) + +A callback run when the map emits a `load` event. [Mapbox docs](https://www.mapbox.com/mapbox-gl-js/api#map.event:load) ##### `onError` {Function} - default: `no-op function` -A callback run when the map emits an `error` event. -[Mapbox docs](https://www.mapbox.com/mapbox-gl-js/api#map.event:error) -##### `transformRequest` {Function} - default: `null` -A callback run before the Map makes a request for an external URL. The callback can be used -to modify the url, set headers, or set the credentials property for cross-origin requests. -Expected to return an object with a `url` property and optionally `headers` and `credentials` -properties. Equivalent to Mapbox's `transformRequest` [map option](https://www.mapbox.com/mapbox-gl-js/api#map). +A callback run when the map emits an `error` event. [Mapbox docs](https://www.mapbox.com/mapbox-gl-js/api#map.event:error) + ## Methods ##### `getMap()` -Returns the Mapbox instance if initialized. The `Map` instance will have -full access to [MapboxGL's API](https://www.mapbox.com/mapbox-gl-js/api/#map). + +Returns the Mapbox instance if initialized. The `Map` instance will have full access to [MapboxGL's API](https://www.mapbox.com/mapbox-gl-js/api/#map). ##### `queryRenderedFeatures(geometry, parameters)` -Use Mapbox's `queryRenderedFeatures` API to find features at point or in a bounding box. -If the `parameters` argument is not specified, only queries the layers with the -`interactive` property in the layer style. + +Use Mapbox's `queryRenderedFeatures` API to find features at point or in a bounding box. If the `parameters` argument is not specified, only queries the layers with the `interactive` property in the layer style. Parameters: -- `geometry` {[Number, Number` | [[Number, Number`, [Number, Number``` - Point or an array of two points defining the bounding box. Coordinates in pixels. -- `parameters` - Query options. For more details, see - [Mapbox API documentation](https://www.mapbox.com/mapbox-gl-js/api/#Map#queryRenderedFeatures). +- `geometry` {`[Number, Number` | `[[Number, Number, [Number, Number` - Point or an array of two points defining the bounding box. Coordinates in pixels. +- `parameters` - Query options. For more details, see [Mapbox API documentation](https://www.mapbox.com/mapbox-gl-js/api/#Map#queryRenderedFeatures). ## Source + [static-map.js](https://github.com/uber/react-map-gl/tree/3.2-release/src/components/static-map.js) diff --git a/docs/whats-new.md b/docs/whats-new.md index b2e1cd60..638c120c 100644 --- a/docs/whats-new.md +++ b/docs/whats-new.md @@ -1,10 +1,11 @@ # react-map-gl v3.3 -Release date: In development, target April, 2018 +Release date: In development, target May 25, 2018 -## Hightlights +## Highlights - **New `viewState` Property**: Makes it possible to specify all map state properties (`longitude`, `latitude`, `zoom`, `bearing` and `pitch`) as a single property. +- **New `onViewStateChange` callback**: An alternative callback that matches the new `viewState` prop. # react-map-gl v3.2 diff --git a/examples/reuse-map/src/app.js b/examples/reuse-map/src/app.js index d920e4da..8518d5e9 100644 --- a/examples/reuse-map/src/app.js +++ b/examples/reuse-map/src/app.js @@ -2,24 +2,40 @@ import React, {Component} from 'react'; import {render} from 'react-dom'; import BartMap from './bart-map'; +const LIGHT_STYLE = "mapbox://styles/mapbox/light-v9"; +const DARK_STYLE = "mapbox://styles/mapbox/dark-v9"; + export default class App extends Component { state = { - showMap: true + showMap: true, + mapStyleLight: true }; _toggleMap() { - this.setState({showMap: !this.state.showMap}); + let {showMap, mapStyleLight} = this.state; + + showMap = !this.state.showMap; + if (showMap) { + mapStyleLight = !mapStyleLight; + } + + this.setState({ + showMap, + mapStyleLight + }); } render() { - const {showMap} = this.state; + const {showMap, mapStyleLight} = this.state; + const mapStyle = mapStyleLight ? LIGHT_STYLE : DARK_STYLE; + console.warn(mapStyle); return (
Toggle Map
- {showMap && } + {showMap && }
); } diff --git a/examples/reuse-map/src/bart-map.js b/examples/reuse-map/src/bart-map.js index 4ba9db4d..c7e04823 100644 --- a/examples/reuse-map/src/bart-map.js +++ b/examples/reuse-map/src/bart-map.js @@ -10,14 +10,12 @@ import MARKER_STYLE from './marker-style'; export default class BartMap extends Component { state = { - viewport: { + viewState: { latitude: 37.729, longitude: -122.36, zoom: 11, bearing: 0, - pitch: 50, - width: 500, - height: 500 + pitch: 50 }, settings: { dragPan: true, @@ -34,7 +32,7 @@ export default class BartMap extends Component { } }; - _onViewportChange = viewport => this.setState({viewport}); + _onViewportChange = viewState => this.setState({viewState}); _renderMarker(station, i) { const {name, coordinates} = station; @@ -46,14 +44,19 @@ export default class BartMap extends Component { } render() { - const {viewport, settings} = this.state; + const {mapStyle} = this.props; + const {viewState, settings} = this.state; return ( diff --git a/src/mapbox/mapbox.js b/src/mapbox/mapbox.js index 9d859a8c..e3538841 100644 --- a/src/mapbox/mapbox.js +++ b/src/mapbox/mapbox.js @@ -32,6 +32,7 @@ const propTypes = { onLoad: PropTypes.func, /** The onLoad callback for the map */ onError: PropTypes.func, /** The onError callback for the map */ reuseMaps: PropTypes.bool, + reuseMap: PropTypes.bool, transformRequest: PropTypes.func, /** The transformRequest callback for the map */ mapStyle: PropTypes.string, /** The Mapbox style. A string url to a MapboxGL style */ @@ -61,6 +62,7 @@ const defaultProps = { onLoad: noop, onError: noop, reuseMaps: false, + reuseMap: false, transformRequest: null, mapStyle: 'mapbox://styles/mapbox/light-v8', @@ -144,7 +146,7 @@ export default class Mapbox { _create(props) { // Reuse a saved map, if available - if (props.reuseMaps && Mapbox.savedMap) { + if ((props.reuseMaps || props.reuseMap) && Mapbox.savedMap) { this._map = this.map = Mapbox.savedMap; // When reusing the saved map, we need to reparent the map(canvas) and other child nodes // intoto the new container from the props. @@ -158,6 +160,12 @@ export default class Mapbox { // Step2: replace the internal container with new container from the react component this._map._container = newContainer; Mapbox.savedMap = null; + + // Update style + if (props.mapStyle) { + this._map.setStyle(props.mapStyle); + } + // TODO - need to call onload again, need to track with Promise? props.onLoad(); } else {