Skip to content

Commit

Permalink
feat(StreetViewPanorama): add StreetViewPanorama component
Browse files Browse the repository at this point in the history
  • Loading branch information
novascreen authored and Thomas Hermann committed Jun 1, 2017
1 parent 29d20f6 commit e75c936
Show file tree
Hide file tree
Showing 9 changed files with 254 additions and 0 deletions.
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,13 @@ render(
/>
```

### StreetViewPanorama
```jsx
<StreetViewPanorama
element={<div>Optional placeholder to render StreetView panorama separate from map</div>}
/>
```

### drawing/DrawingManager

```jsx
Expand Down
2 changes: 2 additions & 0 deletions src/app/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import {
FusionTablesLayerExample,
PopUpInfoWindowExample,
TrafficLayerExample,
StreetViewPanoramaExample,
} from "./pages/basics";

import {
Expand Down Expand Up @@ -78,6 +79,7 @@ export default class App extends Component {
<Route path="fusion-tables-layer" component={FusionTablesLayerExample} />
<Route path="pop-up-window" component={PopUpInfoWindowExample} />
<Route path="traffic-layer" component={TrafficLayerExample} />
<Route path="streetview-panorama" component={StreetViewPanoramaExample} />
</Route>
<Route path="events">
<Route path="simple-click-event" component={SimpleClickEventExample} />
Expand Down
1 change: 1 addition & 0 deletions src/app/containers/Application.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ export default class Application extends Component {
<LinkContainer to="/basics/fusion-tables-layer"><MenuItem>Fusion Tables Layer</MenuItem></LinkContainer>
<LinkContainer to="/basics/pop-up-window"><MenuItem>Pop-up InfoWindow</MenuItem></LinkContainer>
<LinkContainer to="/basics/traffic-layer"><MenuItem>Traffic Layer</MenuItem></LinkContainer>
<LinkContainer to="/basics/streetview-panorama"><MenuItem>StreetView Panorama</MenuItem></LinkContainer>
<MenuItem divider />
<LinkContainer to="/events/simple-click-event"><MenuItem>Simple click event</MenuItem></LinkContainer>
<LinkContainer to="/events/closure-listeners">
Expand Down
55 changes: 55 additions & 0 deletions src/app/pages/basics/StreetViewPanoramaExample.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/* global google */
import {
default as React,
Component,
} from "react";

import {
withGoogleMap,
GoogleMap,
StreetViewPanorama,
} from "../../../lib";

const coordinates = { lat: 49.2853171, lng: -123.1119202 };

const StreetViewPanoramaExampleGoogleMap = withGoogleMap(props => (
<GoogleMap
defaultZoom={8}
defaultCenter={coordinates}
>
<StreetViewPanorama
defaultPosition={coordinates}
visible
/>
</GoogleMap>
));

/**
* You can pass in an `element` to render `StreetViewPanorama` in its own container
* At this point the `GoogleMap` wrapper and `withGoogleMap` HOC become optional, so you can either render map and StreetView
* at the same time, or just the StreetView on its own
* <StreetViewPanorama
* element={<div />}
* defaultPosition={coordinates}
* visible
* />
*/

/*
* Add <script src="https://maps.googleapis.com/maps/api/js"></script> to your HTML to provide google.maps reference
*/
export default class StreetViewPanoramaExample extends Component {

render() {
return (
<StreetViewPanoramaExampleGoogleMap
containerElement={
<div style={{ width: `100%`, height: `50%` }} />
}
mapElement={
<div style={{ width: `100%`, height: `100%` }} />
}
/>
);
}
}
4 changes: 4 additions & 0 deletions src/app/pages/basics/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import PopUpInfoWindowExample from "./PopUpInfoWindowExample";

import TrafficLayerExample from './TrafficLayerExample';

import StreetViewPanoramaExample from "./StreetViewPanoramaExample";

SimpleMapExample.__raw = require(`!raw!./SimpleMapExample`);
StyledMapExample.__raw = require(`!raw!./StyledMapExample`);
GeolocationExample.__raw = require(`!raw!./GeolocationExample`);
Expand All @@ -25,6 +27,7 @@ KmlLayerExample.__raw = require(`!raw!./KmlLayerExample`);
PopUpInfoWindowExample.__raw = require(`!raw!./PopUpInfoWindowExample`);
FusionTablesLayerExample.__raw = require(`!raw!./FusionTablesLayerExample`);
TrafficLayerExample.__raw = require(`!raw!./TrafficLayerExample`);
StreetViewPanoramaExample.__raw = require(`!raw!./StreetViewPanoramaExample`);

export {
SimpleMapExample,
Expand All @@ -36,4 +39,5 @@ export {
PopUpInfoWindowExample,
FusionTablesLayerExample,
TrafficLayerExample,
StreetViewPanoramaExample,
};
177 changes: 177 additions & 0 deletions src/lib/StreetViewPanorama.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
/* global google */
import _ from 'lodash';

import {
default as React,
PropTypes,
} from "react";

import {
MAP,
STREET_VIEW_PANORAMA,
} from "./constants";


import {
addDefaultPrefixToPropTypes,
collectUncontrolledAndControlledProps,
default as enhanceElement,
} from "./enhanceElement";

const controlledPropTypes = {
// NOTICE!!!!!!
//
// Only expose those with getters & setters in the table as controlled props.
//
// [].map.call($0.querySelectorAll("tr>td>code", function(it){ return it.textContent; })
// .filter(function(it){ return it.match(/^set/) && !it.match(/^setMap/); })
//
// https://developers.google.com/maps/documentation/javascript/3.exp/reference#StreetViewPanorama
links: PropTypes.array,
motionTracking: PropTypes.bool,
options: PropTypes.object,
pano: PropTypes.string,
panoProvider: PropTypes.func,
position: PropTypes.object,
pov: PropTypes.object,
visible: PropTypes.bool,
zoom: PropTypes.number,
};

const defaultUncontrolledPropTypes = addDefaultPrefixToPropTypes(controlledPropTypes);

const eventMap = {
// https://developers.google.com/maps/documentation/javascript/3.exp/reference#StreetViewPanorama
// [].map.call($0.querySelectorAll("tr>td>code"), function(it){ return it.textContent; })
onCloseClick: `closeclick`,

onPanoChanged: `pano_changed`,

onPositionChanged: `position_changed`,

onLinksChanged: `links_changed`,

onPovChanged: `pov_changed`,

onResize: `resize`,

onStatusChanged: `status_changed`,

onVisibleChanged: `visible_changed`,

onZoomChanged: `zoom_changed`,

};

const publicMethodMap = {
// Public APIs
//
// https://developers.google.com/maps/documentation/javascript/3.exp/reference#StreetViewPanorama
//
// [].map.call($0.querySelectorAll("tr>td>code"), function(it){ return it.textContent; })
// .filter(function(it){ return it.match(/^get/) && !it.match(/Map$/); })
getLinks(streetViewPanorama) { return streetViewPanorama.getLinks(); },

getLocation(streetViewPanorama) { return streetViewPanorama.getLocation(); },

getMotionTracking(streetViewPanorama) { return streetViewPanorama.getMotionTracking(); },

getPano(streetViewPanorama) { return streetViewPanorama.getPano(); },

getPhotographerPov(streetViewPanorama) { return streetViewPanorama.getPhotographerPov(); },

getPosition(streetViewPanorama) { return streetViewPanorama.getPosition(); },

getPov(streetViewPanorama) { return streetViewPanorama.getPov(); },

getStatus(streetViewPanorama) { return streetViewPanorama.getStatus(); },

getVisible(streetViewPanorama) { return streetViewPanorama.getVisible(); },

getZoom(streetViewPanorama) { return streetViewPanorama.getZoom(); },
// END - Public APIs
};

const controlledPropUpdaterMap = {
links(streetViewPanorama, links) { streetViewPanorama.setLinks(links); },
motionTracking(streetViewPanorama, motionTracking) { streetViewPanorama.setMotionTracking(motionTracking); },
options(streetViewPanorama, options) { streetViewPanorama.setOptions(options); },
pano(streetViewPanorama, pano) { streetViewPanorama.setPano(pano); },
panoProvider(streetViewPanorama, panoProvider) { streetViewPanorama.registerPanoProvider(panoProvider); },
position(streetViewPanorama, position) { streetViewPanorama.setPosition(position); },
pov(streetViewPanorama, pov) { streetViewPanorama.setPov(pov); },
visible(streetViewPanorama, visible) { streetViewPanorama.setVisible(visible); },
zoom(streetViewPanorama, zoom) { streetViewPanorama.setZoom(zoom); },
};

function getInstanceFromComponent(component) {
return component.state[STREET_VIEW_PANORAMA];
}

export default _.flowRight(
React.createClass,
enhanceElement(getInstanceFromComponent, publicMethodMap, eventMap, controlledPropUpdaterMap),
)({
displayName: `StreetViewPanorama`,

propTypes: {
...controlledPropTypes,
...defaultUncontrolledPropTypes,
},

contextTypes: {
[MAP]: PropTypes.object,
},

getInitialOptions() {
return collectUncontrolledAndControlledProps(
defaultUncontrolledPropTypes,
controlledPropTypes,
this.props,
);
},

getInitialState() {
// https://developers.google.com/maps/documentation/javascript/3.exp/reference#StreetViewPanorama
let streetViewPanorama;
if (!this.props.element && this.context[MAP]) {
streetViewPanorama = this.context[MAP].getStreetView();
streetViewPanorama.setOptions(this.getInitialOptions());
}
if (!this.props.element && !this.context[MAP]) {
throw new Error(`You need to use the StreetViewPanorama in the context of \`<GoogleMap>\` or pass an \`element\` for it to be rendered in.`);
}
return {
[STREET_VIEW_PANORAMA]: streetViewPanorama,
};
},

handleComponentMount(el) {
const streetViewPanorama = new google.maps.StreetViewPanorama(el, {
map: this.context[MAP],
...this.getInitialOptions(),
});
if (this.context[MAP]) {
this.context[MAP].setStreetView(streetViewPanorama);
}
this.setState({ [STREET_VIEW_PANORAMA]: streetViewPanorama });
},

componentWillUnmount() {
const streetViewPanorama = getInstanceFromComponent(this);
if (streetViewPanorama) {
streetViewPanorama.setVisible(false);
}
},

render() {
if (this.props.element) {
return (
React.cloneElement(this.props.element, {
ref: this.handleComponentMount,
},
));
}
return false;
},
});
2 changes: 2 additions & 0 deletions src/lib/__tests__/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
Polygon,
Polyline,
Rectangle,
StreetViewPanorama,
} from "../index";

describe(`index`, () => {
Expand All @@ -29,5 +30,6 @@ describe(`index`, () => {
expect(Polygon).toBeDefined();
expect(Polyline).toBeDefined();
expect(Rectangle).toBeDefined();
expect(StreetViewPanorama).toBeDefined();
});
});
2 changes: 2 additions & 0 deletions src/lib/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,5 @@ export const MARKER_CLUSTERER = `__SECRET_MARKER_CLUSTERER_DO_NOT_USE_OR_YOU_WIL
export const INFO_BOX = `__SECRET_INFO_BOX_DO_NOT_USE_OR_YOU_WILL_BE_FIRED`;

export const TRAFFIC_LAYER = `__SECRET_TRAFFIC_LAYER_DO_NOT_USE_OR_YOU_WILL_BE_FIRED`;

export const STREET_VIEW_PANORAMA = `__SECRET_STREET_VIEW_PANORAMA_DO_NOT_USE_OR_YOU_WILL_BE_FIRED`;
4 changes: 4 additions & 0 deletions src/lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,7 @@ export {
export {
default as OverlayView,
} from "./OverlayView";

export {
default as StreetViewPanorama,
} from "./StreetViewPanorama";

0 comments on commit e75c936

Please sign in to comment.