Closed kad3nce closed 8 years ago
In short there are three methods u need to create marker draggable
onChildMouseDown(hoverKey, childProps, mouse)
onChildMouseUp(hoverKey, childProps, mouse)
onChildMouseMove(hoverKey, childProps, mouse)
I have no time to publish working examples now (need to remove proprietary code)
but its easy as make any Item dragable with standard mousedown, mousemove, mouseup
PS: mouse has lat,lng
That’s a huge help, Ivan! No sweat on the examples. I really appreciate you taking the time to reply. I’ll dive in.
All the best,
-Jedidiah
On Wed, Nov 4, 2015 at 12:00 PM, Ivan Starkov notifications@github.com wrote:
In short there are three methods u need to create marker draggable
onChildMouseDown(hoverKey, childProps, mouse) onChildMouseUp(hoverKey, childProps, mouse) onChildMouseMove(hoverKey, childProps, mouse)
I have no time to publish working examples now (need to remove proprietary code) but its easy as make any Item dragable with standard
mousedown, mousemove, mouseup
PS: mouse has
lat,lng
Reply to this email directly or view it on GitHub: https://github.com/istarkov/google-map-react/issues/59#issuecomment-153830959
Hello again @istarkov. I implemented the callbacks and am able to get the events to fire when I interact with a child marker. However, I'm still not sure how to prevent the Google Map itself from being dragged when I'm trying to drag a child object. Any pointers on that?
Thanks again for your help!
Current code:
...
onCircleInteraction(childKey, childProps, mouse) {
// function is just a stub to test callbacks
if (childKey !== 'map-circle') return;
console.log('onCircleInteraction called with', childKey, childProps, mouse);
}
render() {
let center = this.props.mapConfig.center;
return (
<div>
<h2>Welcome to the map!</h2>
<div style={{height:"500px"}}>
<GoogleMap center={center}
defaultZoom={this.props.mapConfig.zoom}
onChildMouseDown={::this.onCircleInteraction}
onChildMouseUp={::this.onCircleInteraction}
onChildMouseMove={::this.onCircleInteraction}>
<MapCircle key="map-circle" lat={center[0]} lng={center[1]} />
{this.geofireMarkers()}
</GoogleMap>
</div>
</div>
);
}
...
O sorry forget to say, map has a boolean draggable
property, just set it to false
in onChildMouseDown
and to true
in onChildMouseUp
@kad3nce I see you've created MapCircle component. How do you get there the map
reference to apply the circle on it? Maybe you could post your implementation for that component, it might be useful.
please someone create a full documented example for draggable markers
@hemedani My example:
import PropTypes from 'prop-types';
import GoogleMapReact from 'google-map-react';
class AnyReactComponent extends Component{
render(){
let {
text,
} = this.props;
return <div
style={{
background: '#fff',
display: 'inline-block',
}}
>{text}</div>
}
}
export default class MapExample extends Component{
contextTypes = {
updateItem: PropTypes.func.isRequired,
}
static defaultProps = {
center: {lat: 59.95, lng: 30.33},
zoom: 11
};
static propTypes = {
PlacesStore: PropTypes.object.isRequired,
};
constructor(props){
super(props);
this.state = {
draggable: true, // By default map is draggable
}
}
onChildMouseDown(){
// set map no draggable
this.setState({
draggable: false,
});
}
onChildMouseUp(){
set map draggable again
this.setState({
draggable: true,
});
}
onChildMouseMove(key, marker, newCoords){
// Change item data with new coordinates
// you need set here own store and update function
let {
item,
} = marker;
let {
PlacesStore
} = this.props;
let {
updateItem,
} = this.context;
PlacesStore.getDispatcher().dispatch(PlacesStore.actions['UPDATE'], item, newCoords);
this.forceUpdate();
}
render(){
let {
PlacesStore
} = this.props;
let {
draggable,
} = this.state;
let items = [];
PlacesStore.getState().map(n => {
// console.log(n);
let {
id,
lat,
lng,
name,
} = n;
items.push(<AnyReactComponent
key={id}
item={n}
lat={lat}
lng={lng}
text={name}
/>);
})
return <GoogleMapReact
draggable={draggable}
defaultCenter={this.props.center}
defaultZoom={this.props.zoom}
apiKey="xxxxxxxxxxxxxxxxx"
onChildMouseDown={::this.onChildMouseDown}
onChildMouseUp={::this.onChildMouseUp}
onChildMouseMove={::this.onChildMouseMove}
>
{items}
</GoogleMapReact>
}
} ```
@Fi1osof Could you please show a working example? Your example does not render a map for me! I put it in CodeSandBox:
https://codesandbox.io/s/llj2kryzqz
Cheers
I suppose you've found your way out, in any case here is the code :
import React from "react"; import { compose, withProps } from "recompose"; import { withScriptjs, withGoogleMap, GoogleMap, Marker } from "react-google-maps"; import { GOOGLE_API_KEY } from "../wherever you have it in Constants";
const MyMapComponent = compose( withProps({ googleMapURL: GOOGLE_API_KEY, loadingElement: <div style={{ height: "give your height" }} />, containerElement: <div style={{ height: "give your height" }} />, mapElement: <div style={{ height: "give your height" }} /> }), withScriptjs, withGoogleMap )(props => ( <GoogleMap defaultZoom={11} defaultCenter={{ lat: whateverLat, lng: whateverLng }}> <Marker position={{ lat: whateverLat, lng: whateverLng }} draggable={true} onClick={props.onMarkerClick} /> ));
class MyFancyComponent extends React.PureComponent { state = { isMarkerShown: false, draggable: true };
onChildMouseDown() { this.setState({ draggable: false }); }
onChildMouseUp() { this.setState({ draggable: true }); }
onChildMouseMove(key, marker, newCoords) { let { item } = marker;
let { PlacesStore } = this.props;
let { updateItem } = this.context;
PlacesStore.getDispatcher().dispatch(
PlacesStore.actions["UPDATE"],
item,
newCoords
);
this.forceUpdate();
}
render() { let { PlacesStore } = this.props;
let { draggable } = this.state;
let items = [ ];
PlacesStore.getState().map(n => {
let { id, lat, lng } = n;
items.push(<MyMapComponent key={id} item={n} lat={lat} lng={lng} />);
});
return (
<MyMapComponent
isMarkerShown={this.state.isMarkerShown}
onMarkerClick={this.handleMarkerClick}
onChildMouseDown={this.onChildMouseDown}
onChildMouseUp={this.onChildMouseUp}
onChildMouseMove={this.onChildMouseMove}
/>
);
} }
export default MyMapComponent;
@hemedani My example:
import PropTypes from 'prop-types'; import GoogleMapReact from 'google-map-react'; class AnyReactComponent extends Component{ render(){ let { text, } = this.props; return <div style={{ background: '#fff', display: 'inline-block', }} >{text}</div> } } export default class MapExample extends Component{ contextTypes = { updateItem: PropTypes.func.isRequired, } static defaultProps = { center: {lat: 59.95, lng: 30.33}, zoom: 11 }; static propTypes = { PlacesStore: PropTypes.object.isRequired, }; constructor(props){ super(props); this.state = { draggable: true, // By default map is draggable } } onChildMouseDown(){ // set map no draggable this.setState({ draggable: false, }); } onChildMouseUp(){ set map draggable again this.setState({ draggable: true, }); } onChildMouseMove(key, marker, newCoords){ // Change item data with new coordinates // you need set here own store and update function let { item, } = marker; let { PlacesStore } = this.props; let { updateItem, } = this.context; PlacesStore.getDispatcher().dispatch(PlacesStore.actions['UPDATE'], item, newCoords); this.forceUpdate(); } render(){ let { PlacesStore } = this.props; let { draggable, } = this.state; let items = []; PlacesStore.getState().map(n => { // console.log(n); let { id, lat, lng, name, } = n; items.push(<AnyReactComponent key={id} item={n} lat={lat} lng={lng} text={name} />); }) return <GoogleMapReact draggable={draggable} defaultCenter={this.props.center} defaultZoom={this.props.zoom} apiKey="xxxxxxxxxxxxxxxxx" onChildMouseDown={::this.onChildMouseDown} onChildMouseUp={::this.onChildMouseUp} onChildMouseMove={::this.onChildMouseMove} > {items} </GoogleMapReact> } } ```
@Fi1osof Thanks man, it really helped. 👍
Hey there! I'm using google-map-react with GeoFire and need to implement a draggable circle as in this demo.
I didn't see any documentation on doing something like this, so decided to try to use the Google Maps API directly. The circle shows up and the hand cursor changes to a pointer when hovering over it, but unfortunately, once I start dragging, the entire map is dragged rather than just the circle. Is there a workaround for this? (example code and screenshot below).
Thanks for the help and for making this great component!
Best, -Jedidiah